remarks net cref c# .net .net-4.0 peverify

net - remarks c#



¿Por qué esta línea causa una VerificationException cuando se ejecuta en.NET 4? (1)

Ayúdame gente: ¿por qué este código causa una VerificationException cuando se ejecuta en .NET 4.0?

public T parseEnum<T>(string value, T defaultValue) { //Removing the following lines fixes the problem if (!typeof(T).IsEnum) throw new ArgumentException("T must be an enumerated type"); return defaultValue; }

peverify en el ensamblado .net 2.0 y recibí el siguiente mensaje:

ImageResizer.Util.Utils :: parseEnum [T]] [offset 0x0000000A] El parámetro ''this'' para la llamada debe ser el parámetro ''this'' del método de llamada.

Esto provoca una VerificationException: Operation could destabilize the runtime mensaje de VerificationException: Operation could destabilize the runtime cuando se ejecuta el código bajo la confianza media.

Ya leí todas las publicaciones similares en desbordamiento de pila, y ninguna de ellas se aplica a este código.

¿Hay algo nuevo en los genéricos que haga que este código sea inválido de algún modo?


El motivo subyacente del error es un cambio en la firma de IsEnum.

En .NET 2.0 (y 3.0), IsEnum no era un método virtual :

public bool IsEnum { get; }

El conjunto emitido para llamarlo es:

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

En .NET 4.0, IsEnum es un método virtual :

public virtual bool IsEnum { get; }

Aquí está la misma línea de ensamblaje para 4.0:

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

El error que está obteniendo se agregó en peverify justo antes de la versión 2.0 y advierte cuando se llama un método virtual de forma no virtual.

Ahora, peverify carga su código, carga .NET 4.0 y luego verifica su código. Como su código llama al método virtual (.NET 4.0) de forma no virtual, se muestra el error.

Uno podría pensar que dado que está compilando contra la versión .NET 2.0, esto debería estar bien, y cargaría el CLR de .NET 2.0 para verificar. No parece así.

Editar:

Para comprobar esto, descargué el SDK de .NET 2.0 y probé el peverify allí. Verifica correctamente el código.

Entonces, el mensaje parece ser el siguiente: use un peverify que coincida con el marco de destino de su código.

Solución:

Parece que la interfaz _Type proporciona una solución a esto:

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

La documentación dice que está diseñado para ser llamado desde un código no administrado, pero como un efecto secundario de que es una interfaz, proporciona un método estable (virtual) para llamar.

He confirmado que funciona con peverify si tiene como objetivo 2.0 o 4.0.