ckv
ckv

Reputation: 10820

Using dynamic types with LINQ

What is the advantage of using dynamic type in the below code?

public static List<dynamic> GetEmployees()
{
    List<Employee> source = GenerateEmployeeCollection();
    var queryResult = from employee in source
                      where employee.Age > 20
                      select new { employee.FirstName, employee.Age };

    return queryResult.ToList<dynamic>();
}

And when would you go for returning a List<dynamic>.

Is to avoid creating types which would be used only very rarely?

Upvotes: 2

Views: 2889

Answers (4)

Ondrej Janacek
Ondrej Janacek

Reputation: 12616

If this method is not a part of the public API and is used only by you or your fellow developers, you can use the Tuple class for this.

public static List<Tuple<string, int>> GetEmployees()
{
    List<Employee> source = GenerateEmployeeCollection();
    var queryResult = from employee in source
                      where employee.Age > 20
                      select Tuple.Create(employee.FirstName, employee.Age);

    return queryResult.ToList();
}

Then access values as follows

var emps = GetEmployees();
var firstEmpName = emps[0].Item1; // FirstName
var firstEmpage = emps[0].Item2; // Age

I don't recommed to use it as a part of a public API since it's not clear which item contais what value. However, for the private usage sake, it's a nice way to get a temporary class for data.

Upvotes: 2

Thomas Weller
Thomas Weller

Reputation: 11717

This clearly is a misuse of dynamic keyword - it should be used ONLY for object instances for which the type cannot be defined at the time of coding (which is e.g. the case when interacting with dynamic languages like Python). The author was just too lazy to define a type that he could return from the method.

Instead, the above code should be changed to this:

public class Person
{
    public string FirstName { get; private set; }
    public int Age { get; private set; }

    public Person(string firstName, int age)
    {
        FirstName = firstName;
        Age = age;
    }
}
...
public static List<Person> GetEmployees()
{
    List<Employee> source = GenerateEmployeeCollection();
    var queryResult = from employee in source
                      where employee.Age > 20
                      select new Person(employee.FirstName, employee.Age);

    return queryResult.ToList();
}

Regarding ToList(): The call to ToList() makes sense, since it 'materializes' the result of the previous LINQ query. Otherwise, the query would defer execution until actually iterated - and this is mostly not desirable in such scenarios as above (but note that you can drop the type argument here, it's inferred by the compiler anyway).

Upvotes: 3

Tim S.
Tim S.

Reputation: 56536

A method cannot return an anonymous type (that's what you create with new { employee.FirstName, employee.Age }). Using dynamic bypasses this problem.

I wouldn't recommend using dynamic in this way: Either return Employee, or create another type with just those properties. The main reason is that dynamic doesn't explicitly tell those using GetEmployees what properties are available. It also has a minor runtime performance hit since it must resolve the property name at runtime.

Upvotes: 2

Justin Niessner
Justin Niessner

Reputation: 245399

Using anonymous types is great if you're making a query and only you are consuming the results in your method.

In this case, you're returning the data from your method. When returning data from a method, you want the consumer to know exactly what to expect (which they obviously don't with a dynamic type). Therefore, using a dynamic type is certainly not a good idea.

Upvotes: 6

Related Questions