Pergunta

Eu tenho jogado com PostSharp um pouco e eu corri para um problema desagradável.

A seguir IL em Silverlight assembly:

.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$0000)
    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 
}

gatilhos System.Security.VerificationException: Operação poderia desestabilizar o tempo de execução. exceção. Refletor analisa-lo OK. O que poderia ser errado com ele?

Update 1 Código pretende trabalho da seguinte forma:

public void set_AccountProfileModifiedAt(DateTime value)
{
    bool propertyHasChanged = this.AccountProfileModifiedAt != value;
    this.accountProfileModifiedAt = value;
    if (propertyHasChanged)
    {
        this.NotifyPropertyChanged("AccountProfileModifiedAt");
    }
}

Update 2 Eu fico especificado exceção dentro do próprio

setter

Update 3 Fazer chamadas não-estáticos como callvirt (NotifyPropertyChanged) não ajuda

Update 4 Comentando out (para fins de teste) Código:

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

e substituindo L_001e: brtrue.s L_002b com L_001e:. S largo L_002b faz o truque, mas é um retorno incondicional - não o que eu quero

Update 5 Se eu usar o compilador C # para o comportamento exigido mímico (eu ainda preciso fazer isso com PostSharp) Eu obter seguinte IL:

.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$0000)
    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 
}

Nota existem pequenas diferenças - s largo extras saltar L_0016 e alguns estranho salto L_001e: brtrue.s L_002b. Na versão do compilador fico salto direto para ret.

Foi útil?

Solução

Você usou PEVerify? Você deve sempre executar este utilitário quando jogar diretamente com MSIL (você pode usar o sinalizador msbuild / p: PostSharpVerify = true).

Olhando para o seu código:

  1. As suas variáveis ??locais não são inicializados (faltando "init" palavra-chave). Este é um estabelecimento de MethodBodyDeclaration.

  2. Você está usando um 'licença' em vez de 'jmp' fora de um bloco protegido; isso é inútil, mas não deve importar.

Boa sorte,

-gael

Outras dicas

É difícil dizer - você tem um rastreamento de pilha? Essa exceção geralmente é lançada quando o CLR é incapaz de verificar o tipo-segurança de seu código. Como isso poderia ter vindo de este código ou a partir de qualquer um dos métodos ou tipos que você está usando, será difícil dizer qual é o problema sem um traço de pilha.

Aqui está um post que lida com esse erro. Eu não sei se o seu caso particular é causada pelo mesmo problema, mas, em geral, parece que isso tem a ver com a segurança de acesso de código e verificação. Se for esse o caso, refletor será capaz de ler a IL muito bem, mas o sistema CAS vai chutá-la para fora, por razões desconhecidas.

Parece que você tem uma propriedade setter chama em um monte de outros objetos. Você deve passar por essas outras chamadas de método que procuram grandes declarações switch, no caso, é a questão específica mencionado no post.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top