Why does this line cause a VerificationException when running under .NET 4?

后端 未结 1 1116
礼貌的吻别
礼貌的吻别 2021-02-12 15:08

Help me out folks - why does this code cause a VerificationException when run under .NET 4.0?

public  T parseEnum(string value, T defaultValue) {
  //Re         


        
1条回答
  •  北荒
    北荒 (楼主)
    2021-02-12 15:43

    The underlying reason for the error is a change in the signature of IsEnum.

    In .NET 2.0 (and 3.0), IsEnum wasn't a virtual method:

    public bool IsEnum { get; }
    

    The assembly emitted to call it is:

    call instance bool [mscorlib]System.Type::get_IsEnum()
    

    In .NET 4.0, IsEnum is a virtual method:

    public virtual bool IsEnum { get; }
    

    Here is the same line of assembly for 4.0:

    callvirt instance bool [mscorlib]System.Type::get_IsEnum()
    

    The error you're getting was added in peverify just before the 2.0 release, and warns when a virtual method is called non-virtually.

    Now, peverify loads up your code, loads .NET 4.0, and then checks your code. Since your code calls the (.NET 4.0) virtual method non-virtually, the error is shown.

    One would think that since you're building against the .NET 2.0 version, this should be fine, and it would load the .NET 2.0 CLR to check. It doesn't seem so.

    Edit:

    In order to check this, I downloaded .NET 2.0's SDK and tried the peverify in there. It correctly verifies the code.

    So the message would seem to be this: use a peverify which matches the target framework of your code.

    Solution:

    It seems that the _Type interface provides a solution to this:

    if (((_Type)typeof(T)).IsEnum) ...
    

    The documentation says it is designed to be called from unmanaged code, but as a side effect of it being an interface, it provides a stable (virtual) method to call.

    I have confirmed that it works with peverify whether you target 2.0 or 4.0.

    0 讨论(0)
提交回复
热议问题