oscilatingcretin
oscilatingcretin

Reputation: 10919

How do I specify a delegate's return type without upcasting?

I have this class:

class MyClass
{
    public int Id { get; set; }
}

I can create this concrete method with a return type of object and return the integer Id without upcasting:

object ConcreteGetId(MyClass mc)
{
    return mc.Id;
}

However, when I try to generate a delegate using expressions...

static Delegate GenerateGetId()
{
    Type MyType = typeof(MyClass);

    ParameterExpression EntityParameter = Expression.Parameter(MyType);
    MemberExpression Property = Expression.Property(EntityParameter, MyType.GetProperty("Id"));
    LambdaExpression Lambda = Expression.Lambda(Property, EntityParameter);

    Delegate d = Lambda.Compile();

    return d;
}

...the return type is always integer:

.Lambda #Lambda1<System.Func`2[MyNamespace.MyClass,System.Int32]>(MyNamespace.MyClass $var1)
{
    $var1.Id
}

I want it to compile to Func<MyClass, object>, but the only way I know how to do this is to upcast Id to object like this:

LambdaExpression Lambda = Expression.Lambda(Expression.TypeAs(Property, typeof(object)), EntityParameter);

That compiles to this:

.Lambda #Lambda1<System.Func`2[MyNamespace.MyClass,System.Object]>(MyNamespace.MyClass $var1)
{
    $var1.Id .As System.Object
}

I've been reading that there are slight performance hits to casting, so I'd rather not cast at all. Plus, there's no point in upcasting since an object is always every type in the hierarchy above it.

And perhaps this isn't even a problem at all, that it's not really casting, that it just appears it is when looking at the expression's debug info.

Upvotes: 1

Views: 108

Answers (1)

Thomas Levesque
Thomas Levesque

Reputation: 292465

It's not possible to do it without a cast. In your ConcreteGetId method, there is a cast to object, it's just not explicit.

Upvotes: 2

Related Questions