Why does Type.IsGenericType return TRUE for Task without return type obtained by reflection from method but typeof(Task).IsGenericTyp returns FALSE

China☆狼群 提交于 2019-12-22 17:37:32

问题


Can someone explain this? Per documentation IsGenericType

indicatesing whether the current Type represents a type parameter in the definition of a generic type or method.

So this (LINQPad) code:

bool bStraight = typeof(Task).IsGenericType;
bStraight.Dump("typeof(Task).IsGenericType");

works as expected and yields the output:

typeof(Task).IsGenericType
False

But when I retrieve it from a method by reflection:

public class MyClass
{
    public async Task Method()
    {
        await Task.Run(() =>
        {
            Thread.Sleep(3000);
        });
    }
}

public async Task TEST()
{
    MyClass theObject = new MyClass();

    Task task = (Task)typeof(MyClass).GetTypeInfo()
                            .GetDeclaredMethod("Method")
                            .Invoke(theObject, null);

    bool b = task.GetType().IsGenericType;  
    bool b2 = task.GetType().GetGenericTypeDefinition() == typeof(Task<>);
    b.Dump("IsGenericType");
    b2.Dump("GetGenericTypeDefinition");

    bool bStraight = typeof(Task).IsGenericType;
    bStraight.Dump("typeof(Task).IsGenericType");
}

I get the unexpected output of :

IsGenericType
True

GetGenericTypeDefinition
True


回答1:


In some situations, the framework returns a Task<VoidTaskResult> disguised as a Task. Imagine you have some logic relying on TaskCompletionSource<T>. If you don't actually intend to return a result, you still have to fill the T generic parameter. You could use TaskCompletionSource<object>, but you would be wasting a pointer worth of memory (4 bytes in 32 bit, 8 bytes in 64 bit). To avoid that, the framework uses an empty struct: VoidTaskResult.



来源:https://stackoverflow.com/questions/52447267/why-does-type-isgenerictype-return-true-for-task-without-return-type-obtained-by

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!