Anonymous Types in C#

Mastering Lightweight Data Structures for Flexible Code

C# gives developers many ways to represent data – from full classes and records to structs and tuples.
But sometimes, you need a quick, lightweight object just to hold some data without defining a whole class.

That’s where Anonymous Types come in.
They’re simple, fast to use, and perfect for one-off projections, especially in LINQ queries.


🔹 What Are Anonymous Types?

Anonymous types let you create an object without defining a class.
The compiler automatically creates a type behind the scenes — complete with properties, typing, and read-only behavior.

Example:

var person = new { Name = "Alice", Age = 30, City = "London" };

Console.WriteLine($"{person.Name}, {person.Age}, {person.City}");

Output:

Alice, 30, London

Key Points:

  • The var keyword is required because the type name is generated automatically.
  • Properties are read-only (you can’t change them after creation).
  • Anonymous types are type-safe — the compiler enforces property names and types.

🔹 Why Use Anonymous Types?

Anonymous types are ideal when you:

  • Need quick, temporary data containers
  • Want to return or group data from LINQ queries
  • Don’t want to create full classes just for display or transformation
  • Are working with projections (custom shapes of data)

🔹 Creating Anonymous Types

Anonymous types are defined with the new { } syntax:

var book = new { Title = "1984", Author = "George Orwell", Price = 12.99 };

You can mix strings, numbers, and even nested anonymous types:

var order = new
{
    OrderId = 101,
    Customer = new { Name = "John", Email = "john@example.com" },
    Total = 49.99
};

Accessing properties:

Console.WriteLine(order.Customer.Name); // John

🔹 Type Inference and Property Names

When creating an anonymous type, C# automatically infers the property types.
You can also use existing variables as shorthand.

Example:

string product = "Laptop";
double price = 799.99;

var item = new { product, price };
Console.WriteLine($"{item.product} - £{item.price}");

Output:

Laptop - £799.99

✅ C# automatically names the properties product and price — based on the variable names.


🔹 Anonymous Types in LINQ Queries

Anonymous types are used extensively in LINQ projections to shape query results.

Example:

var students = new[]
{
    new { Name = "Alice", Score = 85 },
    new { Name = "Bob", Score = 72 },
    new { Name = "Clara", Score = 90 }
};

var results =
    from s in students
    where s.Score > 75
    select new
    {
        Student = s.Name,
        Grade = s.Score >= 85 ? "A" : "B"
    };

foreach (var r in results)
    Console.WriteLine($"{r.Student}: {r.Grade}");

Output:

Alice: A
Clara: A

What’s Happening:

  • select new { ... } creates an anonymous type per result
  • Each object has Student and Grade properties
  • No class definition needed — it’s generated automatically

🔹 Anonymous Types Are Immutable

All properties of anonymous types are read-only.
This ensures safety when used in queries or projections.

Example:

var car = new { Make = "Tesla", Model = "Model 3" };

// car.Make = "Ford"; ❌  Error: Property is read-only

🔧 Tip:
If you need mutable objects, define a small class or record instead.


🔹 Nested Anonymous Types

You can even nest anonymous types to structure data hierarchically:

var employee = new
{
    Name = "Sarah",
    Address = new { Street = "12 High St", City = "Bristol" },
    Skills = new[] { "C#", "SQL", "Azure" }
};

Console.WriteLine($"{employee.Name} from {employee.Address.City}");

Output:

Sarah from Bristol

🔹 Limitations of Anonymous Types

While convenient, anonymous types have a few restrictions:

LimitationDescription
Read-onlyProperties cannot be changed after creation
Scope-limitedType exists only within the method or project assembly
No explicit type nameYou can’t specify it as a return type or class property
Not suited for APIsShouldn’t be used for public interfaces or serialization

Use them for: internal data transformations, temporary grouping, or UI display logic.
Avoid them for: data models, DTOs, or API responses.


🧩 Real-World Example – Combining Anonymous Types and LINQ

var products = new[]
{
    new { Name = "Laptop", Price = 1200 },
    new { Name = "Mouse", Price = 25 },
    new { Name = "Keyboard", Price = 45 },
    new { Name = "Monitor", Price = 200 }
};

var summary =
    from p in products
    where p.Price > 30
    orderby p.Price descending
    select new
    {
        Product = p.Name,
        Discounted = p.Price * 0.9,
        Category = p.Price > 500 ? "Premium" : "Standard"
    };

foreach (var s in summary)
    Console.WriteLine($"{s.Product} - £{s.Discounted} ({s.Category})");

Output:

Laptop - £1080 (Premium)
Monitor - £180 (Standard)
Keyboard - £40.5 (Standard)

📚 Summary

ConceptDescriptionExample
Anonymous TypeObject created without defining a classnew { Name = "James", Age = 59 }
Property AccessAccess fields with dot notationperson.Name
ImmutabilityProperties can’t be changedRead-only by design
LINQ UseShape query resultsselect new { p.Name, p.Price }

✅ Best Practices

  • Use anonymous types for short-lived, internal data representations
  • Avoid using them as method parameters or return types
  • Keep property names clear and descriptive
  • Use select new { ... } to make LINQ queries cleaner
  • For complex data models, use records or classes instead

🧪 Challenge Task

Create a LINQ query that produces an anonymous type for each employee:

  • Use a where filter to include only those with Salary > £40,000
  • Use select new { Name, Department, AnnualTax = Salary * 0.2 }
  • Print out results as:
    “James (IT) pays £12,000 tax.”

Example dataset:

var employees = new[]
{
    new { Name = "James", Department = "IT", Salary = 60000 },
    new { Name = "Anna", Department = "HR", Salary = 38000 },
    new { Name = "Liam", Department = "Finance", Salary = 45000 }
};

👨‍💻 Want More?

Learn more C# LINQ on our Advanced C# Course covers:

  • Anonymous types and projections
  • Tuples, records, and data shaping
  • Query comprehension and transformation
  • Real-world exercises with LINQ to Objects and SQL

Build confidence writing clear, type-safe, and expressive C# code — without unnecessary boilerplate.

Contact James to learn more