Pregunta

He estado jugando con PostSharp un poco y me encontré con un problema desagradable.

Siguiendo IL en el ensamblaje de Silverlight:

.method public hidebysig specialname newslot virtual final instance void 
set_AccountProfileModifiedAt(valuetype [mscorlib]System.DateTime 'value') cil managed
{
    .maxstack 2
    .locals (
        [0] bool ~propertyHasChanged,
        [1] bool CS$4
public void set_AccountProfileModifiedAt(DateTime value)
{
    bool propertyHasChanged = this.AccountProfileModifiedAt != value;
    this.accountProfileModifiedAt = value;
    if (propertyHasChanged)
    {
        this.NotifyPropertyChanged("AccountProfileModifiedAt");
    }
}
) L_0000: nop L_0001: nop L_0002: ldarg.0 L_0003: call instance valuetype [mscorlib]System.DateTime Accounts.AccountOwner::get_AccountProfileModifiedAt() L_0008: ldarg.1 L_0009: call bool [mscorlib]System.DateTime::op_Inequality(valuetype [mscorlib]System.DateTime, valuetype [mscorlib]System.DateTime) L_000e: stloc.0 L_000f: ldarg.0 L_0010: ldarg.1 L_0011: stfld valuetype [mscorlib]System.DateTime Accounts.AccountOwner::accountProfileModifiedAt L_0016: br.s L_0018 L_0018: ldloc.0 L_0019: ldc.i4.0 L_001a: ceq L_001c: stloc.1 L_001d: ldloc.1 L_001e: brtrue.s L_002b L_0020: ldarg.0 L_0021: ldstr "AccountProfileModifiedAt" L_0026: call instance void Accounts.AccountOwner::NotifyPropertyChanged(string) L_002b: nop L_002c: leave.s L_002e L_002e: ret }

activa System.Security.VerificationException: la operación podría desestabilizar el tiempo de ejecución. excepción. El reflector lo analiza OK. ¿Qué podría estar mal con él?

Actualización 1 El código está diseñado para funcionar de la siguiente manera:

L_0018: ldloc.0 
L_0019: ldc.i4.0 
L_001a: ceq 
L_001c: stloc.1 
L_001d: ldloc.1 

Actualización 2 Obtengo una excepción específica dentro del configurador mismo

Actualización 3 Hacer llamadas no estáticas como callvirt (NotifyPropertyChanged) no ayuda

Actualización 4 Código de comentarios (para fines de prueba):

.method public hidebysig specialname newslot virtual final instance void 

set_AccountProfileModifiedAt(valuetype [mscorlib]System.DateTime 'value') cil managed
{
    .maxstack 2
    .locals init (
        [0] bool val,
        [1] bool CS$4<*>)
    L_0000: nop 
    L_0001: ldarg.0 
    L_0002: call instance valuetype [mscorlib]System.DateTime 

Accounts.AccountOwner::get_AccountProfileModifiedAt()
    L_0007: ldarg.1 
    L_0008: call bool [mscorlib]System.DateTime::op_Inequality(valuetype 

[mscorlib]System.DateTime, valuetype [mscorlib]System.DateTime)
    L_000d: stloc.0 
    L_000e: ldarg.0 
    L_000f: ldarg.1 
    L_0010: stfld valuetype [mscorlib]System.DateTime 

Accounts.AccountOwner::accountProfileModifiedAt
    L_0015: ldloc.0 
    L_0016: ldc.i4.0 
    L_0017: ceq 
    L_0019: stloc.1 
    L_001a: ldloc.1 
    L_001b: brtrue.s L_0029
    L_001d: ldarg.0 
    L_001e: ldstr "AccountProfileModifiedAt"
    L_0023: call instance void 

Accounts.AccountOwner::NotifyPropertyChanged(string)
    L_0028: nop 
    L_0029: ret 
}

y reemplazando L_001e: brtrue.s L_002b con L_001e: br.s L_002b hace el truco pero es un retorno incondicional, no es lo que quiero.

Actualización 5 Si uso el compilador de C # para imitar el comportamiento requerido (todavía tengo que hacer eso con Postsharp) Me sale la siguiente IL:

<*>

Tenga en cuenta que hay pequeñas diferencias: los br.s extra saltan a L_0016 y algunos saltos extraños L_001e: brtrue.s L_002b. En la versión del compilador obtengo salto directo a ret.

¿Fue útil?

Solución

¿Usaste Peverify? Siempre debes ejecutar esta utilidad cuando juegues directamente con MSIL (puedes usar el / msbild flag / p: PostSharpVerify = true).

Mirando tu código:

  1. Sus variables locales no están inicializadas (falta la palabra " init " init). Esta es una propiedad de MethodBodyDeclaration.

  2. Estás utilizando un 'leave' en lugar de un 'jmp' fuera de un bloque protegido; esto es inútil pero no debería importar.

Buena suerte,

-gael

Otros consejos

Es difícil decirlo: ¿tienes un rastro de pila? Esta excepción generalmente se lanza cuando el CLR no puede verificar la seguridad de tipo de su código. Como esto podría provenir de este código o de cualquiera de los métodos o tipos que está utilizando, será difícil decir cuál es el problema sin un seguimiento de la pila.

Aquí hay una publicación que se ocupa de ese error. No sé si su caso particular es causado por el mismo problema, pero en general parece que esto tiene que ver con la seguridad y la verificación del acceso al código. Si ese es el caso, Reflector podrá leer el IL bien, pero el sistema CAS lo echará fuera por razones desconocidas.

Parece que tienes un establecedor de propiedades llamando a un montón de otros objetos. Debes pasar por esos otros métodos de llamadas en busca de grandes declaraciones de cambio, en caso de que sea el problema específico mencionado en la publicación.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top