문제

나는 PostSharp를 조금 가지고 놀았고 나는 불쾌한 문제에 부딪쳤다.

Silverlight 어셈블리에서 IL 다음 :

.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 
}

Triggers System.security.verificationException : 작동이 런타임을 불안정화 할 수 있습니다. 예외. 반사기는 괜찮습니다. 그것에 무엇이 잘못되었을 수 있습니까?

업데이트 1코드는 다음과 같이 작동하기위한 것입니다.

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

업데이트 2세터 자체 내에서 지정된 예외를 얻습니다

업데이트 3비 정적 호출이 CallVirt (NotifyPropertyChanged)로 만드는 것은 도움이되지 않습니다.

업데이트 4주석 (테스트 목적) 코드 :

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_001E로 대체합니다 : Br.S L_002B는 트릭을 수행하지만 무조건적인 수익입니다.

업데이트 5C# 컴파일러를 사용하여 필요한 동작을 모방 한 경우 (여전히 PostSharp로 수행해야합니다) 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 
}

L_0016에서의 추가 Br.s 점프 및 이상한 점프 L_001E : Brtrue.s L_002B. 컴파일러 버전에서는 RET로 직접 점프합니다.

도움이 되었습니까?

해결책

Peverify를 사용 했습니까? MSIL로 직접 재생할 때는 항상이 유틸리티를 실행해야합니다 (MSBuild 플래그 /P : PostSharPverify = true).

코드보기 :

  1. 로컬 변수는 초기화되지 않았습니다 ( "Init"키워드 누락). 이것은 MethodBodyDeclaration의 속성입니다.

  2. 보호 된 블록에서 'JMP'대신 'Leave'를 사용하고 있습니다. 이것은 쓸모가 없지만 중요하지 않아야합니다.

행운을 빕니다,

-게일 사람

다른 팁

말하기 어렵다 - 스택 추적이 있습니까? 이 예외는 일반적으로 CLR이 코드의 유형 안전성을 확인할 수 없을 때 발생합니다. 이것은이 코드 나 사용중인 방법이나 유형에서 나올 수 있으므로 스택 추적이없는 문제가 무엇인지 말하기가 어렵습니다.

여기에 있습니다 그 오류를 다루는 게시물. 귀하의 특정 사례가 동일한 문제로 인해 발생하는지는 모르겠지만 일반적으로 코드 액세스 보안 및 검증과 관련이있는 것처럼 보입니다. 이 경우 반사판은 IL을 잘 읽을 수 있지만 CAS 시스템은 알려지지 않은 이유로 시작합니다.

다른 물체를 부르는 속성 세터가있는 것 같습니다. 게시물에 언급 된 특정 문제 인 경우 Big Switch 문을 찾는 다른 방법 호출을 살펴 봐야합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top