Creating Generic Lists of Anonymous Types in C#: A Comprehensive Study

Nov 19, 2025 · Programming · 29 views · 7.8

Keywords: C# | Anonymous Types | Generic Lists | Type Inference | LINQ

Abstract: This paper provides an in-depth analysis of various techniques for creating generic lists of anonymous types in C#. By examining core concepts such as type inference mechanisms, generic methods, and dynamic types, it详细介绍介绍了different implementation approaches including ToArray().ToList(), custom generic methods, dynamic types, and object types. The article compares the advantages and disadvantages of each method through concrete code examples and offers best practice recommendations for real-world development scenarios.

Fundamental Concepts of Anonymous Types and Generic Lists

In C# 3.0 and later versions, anonymous types provide a convenient way to create object instances without explicitly defining classes. Anonymous types are automatically generated by the compiler at compile time, containing a set of read-only properties whose specific types are inferred by the compiler based on property initialization expressions. This feature is particularly useful for temporary data containers or rapid prototyping.

However, since the type names of anonymous types are generated by the compiler and invisible to developers, using them directly in generic collections presents challenges in type declaration. For example, attempting to use syntax like List<var> is not permitted in C#, because var is a keyword for compile-time type inference and cannot be used as a generic type parameter.

Solutions Based on Type Inference

The most elegant solution leverages C#'s type inference mechanism. By calling generic methods, the compiler can automatically infer the actual type of anonymous types based on the passed parameters, thereby creating corresponding generic lists.

The first recommended approach uses LINQ's ToList() extension method combined with array initialization:

var o = new { Id = 1, Name = "Foo" };
var o1 = new { Id = 2, Name = "Bar" };
var list = new[] { o, o1 }.ToList();

This method works by first creating an array of anonymous types, where the array type is inferred by the compiler as new { int Id, string Name }[] based on the array elements, then calling the ToList() method to convert the array to List<new { int Id, string Name }>. The entire process automatically handles type inference through the compiler, requiring no developer attention to specific type names.

Implementation with Custom Generic Methods

Another flexible approach involves creating custom generic methods that utilize type inference through method parameters to achieve anonymous type list creation:

public static List<T> CreateList<T>(params T[] elements)
{
    return new List<T>(elements);
}

// Usage example
var list = CreateList(o, o1);

The advantage of this method lies in its superior code reusability. By defining the CreateList method once, it can be reused throughout the project. The compiler infers the specific type of T based on the passed parameters o and o1, thereby creating the correct generic list.

Alternative Approaches Using Dynamic and Object Types

Beyond type inference-based methods, dynamic types or object types can serve as compromise solutions.

Using dynamic types avoids compile-time type checking:

var anonymousObjects = new[] 
{ 
    new { Number = 10, Name = "Smith" },
    new { Number = 10, Name = "John" } 
};
List<dynamic> dynamicList = new List<dynamic>(anonymousObjects);

Using object types leverages the fact that all types inherit from object:

List<object> objectList = new List<object>(anonymousObjects);

It's important to note that both approaches lose the strong typing information of the original anonymous types. When accessing list elements, type conversion or dynamic binding is required, which may impact code readability and performance.

Application in Loop Scenarios

In practical development, there's often a need to dynamically build anonymous type lists within loops. While List<var> cannot be used directly, the following pattern can achieve the goal:

var tempList = new List<object>();

while (condition)
{
    // Processing logic
    var item = new { Id = x, Name = y };
    tempList.Add(item);
    // Additional processing logic
}

// If strong typing access is needed, conversion can be performed before usage
var typedList = tempList.Cast<dynamic>().ToList();

Performance and Type Safety Considerations

When selecting specific implementation approaches, trade-offs between type safety and performance requirements must be considered:

In actual projects, type inference-based solutions should be prioritized, reserving dynamic or object types only when dynamic characteristics are genuinely needed.

Conclusion and Best Practices

Creating generic lists of anonymous types is a common requirement in C# development, and this challenge can be elegantly addressed through proper utilization of language features. Key takeaways include:

  1. Understanding the application of type inference mechanisms in generic methods
  2. Mastering the convenient usage of the ToArray().ToList() pattern
  3. Making appropriate choices between type safety and flexibility based on specific scenarios
  4. Employing suitable temporary container strategies in loop construction scenarios

Through the various methods introduced in this article, developers can select the most suitable approach based on specific requirements, ensuring both code simplicity and maintaining good type safety and performance characteristics.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.