Home » c# » Returning anonymous type in C#

Returning anonymous type in C#

Posted by: admin November 30, 2017 Leave a comment

Questions:

I have a query that returns an anonymous type and the query is in a method. How do you write this:

public "TheAnonymousType" TheMethod(SomeParameter)
{
  using (MyDC TheDC = new MyDC())
  {
     var TheQueryFromDB = (....
                           select new { SomeVariable = ....,
                                        AnotherVariable = ....}
                           ).ToList();

      return "TheAnonymousType";
    }
}
Answers:

You can’t.

You can only return object, or container of objects, e.g. IEnumerable<object>, IList<object>, etc.

Questions:
Answers:

You can return dynamic which will give you a runtime checked version of the anonymous type but only in .NET 4+

Questions:
Answers:

You cannot return anonymous types. Can you create a model that can be returned? Otherwise, you must use an object.

Here is an article written by Jon Skeet on the subject

Code from the article:

using System;

static class GrottyHacks
{
    internal static T Cast<T>(object target, T example)
    {
        return (T) target;
    }
}

class CheesecakeFactory
{
    static object CreateCheesecake()
    {
        return new { Fruit="Strawberry", Topping="Chocolate" };
    }

    static void Main()
    {
        object weaklyTyped = CreateCheesecake();
        var stronglyTyped = GrottyHacks.Cast(weaklyTyped,
            new { Fruit="", Topping="" });

        Console.WriteLine("Cheesecake: {0} ({1})",
            stronglyTyped.Fruit, stronglyTyped.Topping);            
    }
}

Or, here is another similar article

Or, as others are commenting, you could use dynamic

Questions:
Answers:

You can use the Tuple class as a substitute for an anonymous types when returning is necessary:

Note: Tuple can have up to 8 parameters.

return Tuple.Create(variable1, variable2);

Or, for the example from the original post:

public List<Tuple<SomeType, AnotherType>> TheMethod(SomeParameter)
{
  using (MyDC TheDC = new MyDC())
  {
     var TheQueryFromDB = (....
                           select Tuple.Create(..., ...)
                           ).ToList();

      return TheQueryFromDB.ToList();
    }
}

http://msdn.microsoft.com/en-us/library/system.tuple(v=vs.110).aspx

Questions:
Answers:

Three options:

Option1:

public class TheRepresentativeType {
    public ... SomeVariable {get;set;}
    public ... AnotherVariable {get;set;}
}

public IEnumerable<TheRepresentativeType> TheMethod(SomeParameter)
{
   using (MyDC TheDC = new MyDC())
   {
     var TheQueryFromDB = (....
                           select new TheRepresentativeType{ SomeVariable = ....,
                                        AnotherVariable = ....}
                           ).ToList();

     return TheQueryFromDB;
   } 
}

Option 2:

public IEnumerable TheMethod(SomeParameter)
{
   using (MyDC TheDC = new MyDC())
   {
     var TheQueryFromDB = (....
                           select new TheRepresentativeType{ SomeVariable = ....,
                                        AnotherVariable = ....}
                           ).ToList();
     return TheQueryFromDB;
   } 
}

you can iterate it as object

Option 3:

public IEnumerable<dynamic> TheMethod(SomeParameter)
{
   using (MyDC TheDC = new MyDC())
   {
     var TheQueryFromDB = (....
                           select new TheRepresentativeType{ SomeVariable = ....,
                                        AnotherVariable = ....}
                           ).ToList();

     return TheQueryFromDB; //You may need to call .Cast<dynamic>(), but I'm not sure
   } 
}

and you will be able to iterate it as a dynamic object and access their properties directly

Questions:
Answers:

C# compiler is a two phase compiler. In the first phase it just checks namespaces, class hierarchies, Method signatures etc. Method bodies are compiled only during the second phase.

Anonymous types are not determined until the method body is compiled.

So the compiler has no way of determining the return type of the method during the first phase.

That is the reason why anonymous types can not be used as return type.

As others have suggested if you are using .net 4.0 or grater, you can use Dynamic.

If I were you I would probably create a type and return that type from the method. That way it is easy for the future programmers who maintains your code and more readable.

Questions:
Answers:
public List<SomeClass> TheMethod(SomeParameter)
{
  using (MyDC TheDC = new MyDC())
  {
     var TheQueryFromDB = (....
                           select new SomeClass{ SomeVariable = ....,
                                        AnotherVariable = ....}
                           ).ToList();

      return TheQueryFromDB.ToList();
    }
}

public class SomeClass{
   public string SomeVariable{get;set}
   public string AnotherVariable{get;set;}
}

Creating your own class and querying for it is the best solution I know.As much as I know you can not use anonymous type return values in another method, because it won’t just be recognized.However, they can be used in the same method.
I used to return them as IQueryable or IEnumerable, though it still does not let you see what is inside of the anonymous type variable.

I run into something like this before while I was trying to refactor some code, you can check it here : Refactoring and creating separate methods

Questions:
Answers:

In C# 7 we can use tuples to accomplish this:

public List<(int SomeVariable, string AnotherVariable)> TheMethod(SomeParameter)
{
  using (MyDC TheDC = new MyDC())
  {
     var TheQueryFromDB = (....
                       select new { SomeVariable = ....,
                                    AnotherVariable = ....}
                       ).ToList();

      return TheQueryFromDB.Select(s => (SomeVariable = s.SomeVariable, AnotherVariable = s.AnotherVariable)).ToList();
  }
}

You might need to install System.ValueTuple nuget package though.

Questions:
Answers:

You can return list of objects in this case.

public List<object> TheMethod(SomeParameter)
{
  using (MyDC TheDC = new MyDC())
  {
     var TheQueryFromDB = (....
                           select new { SomeVariable = ....,
                                        AnotherVariable = ....}
                           ).ToList();

      return TheQueryFromDB ;
    }
}