M Jacob
M Jacob

Reputation: 131

What's the return type of an anonymous class

I have a class that used to have a string return type. Now I find I need to return more than a string. I was thinking to return something like below:

public string Test()
{
  return ( new { ID = 5, Name= "Dave" } );
}

Is this even possible and if so then what would be the return type? I know it's not string ..

Upvotes: 4

Views: 1089

Answers (7)

Nahydrin
Nahydrin

Reputation: 13517

class NewString
{
    public int ID { get; set; }
    public string Name { get; set; }
}

public NewString Test()
{
    return ( new NewString() { ID = 5, Name = "Dave" } );
}

:)

Upvotes: 0

Eric Lippert
Eric Lippert

Reputation: 660435

As others have said, the best thing to do here is to make a nominal type. I would suggest that the nominal type have the same characteristics as an anonymous type; that is, you should consider making the type immutable and consider making it exhibit value equality.

It is possible to return an anonymous type as object and then use the instance returned elsewhere using a variety of sneaky techniques. You can cast the object to "dynamic" (in C# 4) and then use the properties of the anonymous type, but this is slow and lacks compile-time type checking.

You can also use the "cast by example" trick, which does get you compile-time type checking. However, that trick only works when the anonymous source object and the anonymous example object come from the same assembly.

static T CastByExample<T>(object source, T example) where T : class
{
    return source as T;
}

static object ReturnsAnonymous() { return new { X = 123 }; }

static void DoIt()
{
    object obj = ReturnsAnonymous();
    var example = new { X = 0 };
    var anon = CastByExample(obj, example);
    Console.WriteLine(anon.X); // 123
}

See how sneaky that is? We use method type inference and local variable type inference to tell the compiler "these two things are the same type". This lets you export an anonymous type as object and cast it back to anonymous type.

But you probably should not do this; if you're resorting to such sneaky tricks then you should simply be defining a nominal type in the first place. Also, like I said, the trick only works if the example and the source objects were created in code in the same assembly; two "identical" anonymous types in two different assemblies do not unify to be the same type.

Upvotes: 9

Guffa
Guffa

Reputation: 700680

The object that you return does have a class, but it's anonymous so you can't specify it in the code. You just have to return it as an object reference:

public object Test() {
  return new { ID = 5, Name= "Dave" };
}

Note that the anonymous type is unknown outside the scope of the method, so reflection is the only way to access its properties.

If you want to be able to use the returned object conveniently, you should declare a class:

public class TestResult
{
    public int ID { get; set; }
    public string Name { get; set; }
}

public TestResult Test() {
    return new TestResult() { ID = 5, Name= "Dave" };
}

Another alternative is to use an existing class, if it fits your purpose. A KeyValuePair is close to what you use, but then the properties will of course be named Key and Value instead of ID and Name:

public KeyValuePair<int, string> Test() {
  return new KeyValuePair<int, string>(5, "Dave");
}

Upvotes: 3

George Duckett
George Duckett

Reputation: 32448

You can make a struct (or class) for this.

public struct IdAndName
{
    public int Id;
    public string Name;

    public IdAndName(int id, string name)
    {
        ID = id;
        Name = name;
    }
}

You could also use a Tuple<T1, T2>, (but that's not recommended as the properties aren't named.

Upvotes: 0

erikkallen
erikkallen

Reputation: 34411

No, it's not possible. Your options are:

  1. Define a real class for the return value,
  2. Use System.Tuple, or
  3. Use out parameters (probably the least good option).

Upvotes: 0

FIre Panda
FIre Panda

Reputation: 6637

Anonymous type are class type that are derived directly from object.

You can return it from method as object as return type. Have a look at this.

Upvotes: 0

ChrisF
ChrisF

Reputation: 137178

This isn't possible as the anonymous class is only valid within the current context. If you need to return an object then you'll need to create a real class.

I'm assuming you left string as the return type by accident.

Upvotes: 0

Related Questions