Generally, for an object to have some properties, the type of the object has to be defined first. On the contrary, anonymous types provide a convenient way for an object to encapsulate readonly properties without explicitly defining the type first. The type of each property is deduced by the compiler.
Creating an Anonymous Type
- var anonymousType = new { Property = "count", Value = 1 };
- Console.WriteLine(anonymousType.Property, anonymousType.Value);
In the following statement, if we rest our mouse over anonymousType.Property and anonymousType.Value, you will see that their inferred types are string and int.
In the above code, we are initializing a variable with an anonymousType which has its members with specified name as, Property and Value. For the variable anonymousType, the type of its members is inferred by the compiler. You must provide a name for a property that is being initialized with an expression, as in the example above.
It is important to note that class members like events or methods are not valid to be members of an anonymous type. It only contains one or more readonly properties. The expression that is used to initialize a property cannot be null, an anonymous function, or a pointer type.
One another common scenario is to initialize an anonymous type with properties from another object. In the following example, student is an object of type Student which has two properties Id and Name along with some other properties. When we initialize the anonymous type with properties from student, without specifying member (property) names for anonymous type, the compiler gives members the same name as the property being used to initialize them. Hence, anonymousType will also have two properties as Id and Name.
- class Student
- {
- public int Id { get; set; }
- public string FirstName { get; set; }
- public string LastName { get; set; }
- public string City { get; set; }
- }
-
- class Program
- {
- static void Main(string[] args)
- {
- Student student = new Student { Id = 1, Name = "Gaurav Gahlot" };
- var anonymousType = new { student.Id, student.FirstName };
- Console.WriteLine(anonymousType.FirstName);
-
-
- anonymousType.LastName = "someValue";
-
-
- var anyType = new { PropOne = null, PropTwo = 108 };
- }
- }
Using Anonymous Type in LINQ
Anonymous types are typically used in the select clause of a query expression to return a subset of the properties from each object in the source sequence. Assume that studentsList is a collection of Student objects. We can create an anonymous type resultSet using a select query expression with the collection studentsList, as shown in the code below,
- var groupedList = _paymentList.GroupBy(payment => new { PaymentId = payment.PaymentType })
- .Select(
- g => new
- {
- PaymentTypeId = g.Key.PaymentId,
- SumPaymentAmount = g.Sum(row => row.PaymentAmount)
- })
- .ToList();
- Line 1 - we are grouping the _paymentList elements based on anonymous object.
- Line 2 - we are now selecting each element and creating a new anonymous object using its properties.
- Line 4 - we are now returning the collection of these new anonymous objects as a List.
In the above code, what if the required object properties are changed and we need to return more/less data? Do we create a new class or our update the existing one? Well, the best alternative is to use anonymous type.
Since we are creating our object on the fly we cannot use static typing here. And, that's when var comes to our rescue. We declare the variable as an implicitly typed local variable by using var. The type name cannot be specified in the variable declaration because only the compiler has access to the underlying name of the anonymous type.
Bullet Points
- When we use an anonymous type to initialize a variable, we declare the variable as an implicitly typed local variable by using var.
- The type name cannot be specified in the variable declaration because only the compiler has access to the underlying name of the anonymous type.
- The anonymous type declaration starts with the new keyword.
- Anonymous types are class types that derive directly from object, and that cannot be cast to any type except object.
- To pass an anonymous type, or a collection that contains anonymous types, as an argument to a method, you can declare the parameter as type object.
- Equals and GetHashCode methods on anonymous types are defined in terms of the Equals and GetHashCode methods of the properties, therefore two instances of the same anonymous type are equal only if all their properties are equal.
I hope this helps you get a better understanding about the anonymous types and how they can be helpful. It’s always great to have feedback from the readers. Your valuable feedback, questions, or comments about this article are always welcome.