Jens
Jens

Reputation: 2702

Get the Type behind the Interface of the return value

Given this little example code:

class Program
{

    static void Main(string[] args)
    {
        var testInstance = new TestClass();
        Func<TestClass, IComparable> testFunction = (test => test.DoubleProperty);
        var functionType = testFunction.GetType();                       // "Func`2"
        var returnType = testFunction.Method.ReturnType;                 // IComparable
        var typeOfReturnType = testFunction.Method.ReturnType.GetType(); // RuntimeType
    }
}

class TestClass
{
    public int IntProperty { get; set; }

    public double DoubleProperty { get; set; }
}

I would like to get the Type behind IComparable which should be in this case double.

That testFunction.GetType(); will return Func´2 is clear to me.

The return IComparable of testFunction.Method.ReturnType; is also clear and has the value I would expect.

But is it possible to get the original return type double without Invoking the Method testFunction?

Upvotes: 2

Views: 61

Answers (1)

Rob
Rob

Reputation: 27367

After writing my comment, I realized it's a bit more complicated than interpreting the IL, and that it's not definitely doable in all cases.

Consider the function:

Func<TestClass, IComparable> testFunction = test => {
    if (rand.Next(0,2) == 1)
        return new Implementation1();
    else 
        return new Implementation2();
}

There's no way ahead of time to determine which implementation is going to be returned.

However - this also applies to using Expression instead.

The short answer is: 'No', unless your method is fairly well-known at compile time (that is, you know that it will only return one concrete type). Even then, it's a bit tricky.

In your case, it's possible if we know, for example, that the expression is simply a MemberExpression (and in this case, cast to IComparable).

Assuming you defined your expression as follows:

Expression<Func<TestClass, IComparable>> testFunction = (test => test.DoubleProperty);

You could then get the return type with this:

((testFunction.Body as UnaryExpression).Operand as MemberExpression).Type

Upvotes: 3

Related Questions