2009-03-05 11 views
1

私はポストシャープで少し遊んでいましたが、厄介な問題に遭遇しました。CIL:「オペレーションがランタイムを不安定にする可能性があります」例外

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

はSystem.Security.VerificationExceptionをトリガー:操作は、ランタイムを不安定化させることができます。例外。 反射板で解析しても問題ありません。何が間違っているのでしょうか?次のように

アップデート1つの コードが動作するように意図されています。私は非静的を作るセッター自体

アップデート3 内の例外を指定します2

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

更新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を交換する:L_001eでL_002bをbrtrue.s:br.s L_002bは、トリックを行いますが、それは無条件の復帰だ - ではないものをI欲しいです。私は、必要な動作を模倣するためにC#コンパイラを使用している場合

更新5 私はIL次取得(私はまだPostsharpとすることを行う必要があります):

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

注意がマイナーな違いがあります - 余分なBR。 L_0016でジャンプし、いくつかの奇妙なジャンプL_001e:brtrue.s L_002b。コンパイラのバージョンでは、私はすぐにretにジャンプします。

答えて

2

peverifyを使用しましたか? MSILで直接再生する場合は、必ずこのユーティリティを実行する必要があります(msbuildフラグ/ p:PostSharpVerify = trueを使用できます)。

あなたのコードを見てみると:

あなたのローカル変数が初期化されていない
  1. (行方不明 "INIT" キーワード)。これはMethodBodyDeclarationのプロパティです。

  2. 保護されたブロックから 'jmp'の代わりに 'leave'を使用しています。これは無用ですが、問題ではありません。 System.Security.VerificationException:

幸運、スタックの

-gael

0

言うことは難しいです - あなたはスタックトレースを持っていますか?この例外は、通常、CLRがコードの型安全性を検証できない場合にスローされます。これは、このコードか、使用しているメソッドまたはタイプのいずれかから来る可能性があるため、スタックトレースなしで問題が何であるかを言うことは難しいでしょう。

+0

トップは単なるプロパティのセッター:(ある。操作はDomain.Accounts.AccountOwnerでランタイム を不安定化させることができます。 set_AccountProfileModifiedAt(DateTime値) –

0

Here'sそのエラーを扱う記事。あなたの特定のケースが同じ問題によって引き起こされたのかどうかはわかりませんが、一般的に、これはコードアクセスのセキュリティと検証と関係があります。その場合、ReflectorはILをうまく読み取ることができますが、CASシステムは未知の理由でそれを蹴飛ばすでしょう。

プロパティーセッターが他のオブジェクトを呼び出しているようです。あなたは、大きなswitch文を探している他のメソッド呼び出しを調べる必要があります。

+0

これは、それがどのように見えるかです:! BOOL propertyHasChanged = this.AccountProfileModifiedAt =値; this.accountProfileModifiedAt =値; 場合(propertyHasChanged) { this.NotifyPropertyChanged( "AccountProfileModifiedAt"); } IMO他の方法が失敗した場合、setterで失敗しませんか? –

+0

アクセスしている他のメソッド/プロパティの1つによって例外が発生している可能性があります。テストとして、すべてのコードをセッターから引き出し、そのコードがそれを修正するかどうかを確認してください。次に、コードを少しずつ追加して、何が失敗しているのかを正確に把握します。 –

関連する問題