2012-03-29 66 views
2

如果我在反射檢查FieldInfo.SetValueDirect它看起來如下:一個方法如何只包含一個NotImplementedException並且仍然不會拋出?

C#.NET 4.0:

[CLSCompliant(false)] 
public virtual void SetValueDirect(TypedReference obj, object value) 
{ 
    throw new NotSupportedException(Environment.GetResourceString("NotSupported_AbstractNonCLS")); 
} 

而作爲IL:

.method public hidebysig newslot virtual instance void SetValueDirect(valuetype System.TypedReference obj, object 'value') cil managed 
{ 
    .custom instance void System.CLSCompliantAttribute::.ctor(bool) = { bool(false) } 
    .maxstack 8 
    L_0000: ldstr "NotSupported_AbstractNonCLS" 
    L_0005: call string System.Environment::GetResourceString(string) 
    L_000a: newobj instance void System.NotSupportedException::.ctor(string) 
    L_000f: throw 
} 

但是,如果我運行下面的代碼它只是工作

// test struct: 
public struct TestFields 
{ 
    public int MaxValue; 
    public Guid SomeGuid; // req for MakeTypeRef, which doesn't like primitives 
} 


[Test] 
public void SettingFieldThroughSetValueDirect() 
{ 

    TestFields testValue = new TestFields { MaxValue = 1234 }; 

    FieldInfo info = testValue.GetType().GetField("MaxValue"); 
    Assert.IsNotNull(info); 

    // TestFields.SomeGuid exists as a field 
    TypedReference reference = TypedReference.MakeTypedReference(
     testValue, 
     new [] { fields.GetType().GetField("SomeGuid") }); 

    int value = (int)info.GetValueDirect(reference,); 
    info.SetValueDirect(reference, 4096); 

    // assert that this actually worked 
    Assert.AreEqual(4096, fields.MaxValue); 

} 

沒有錯誤發生。 GetValueDirect也是如此。基於資源名稱的猜測是,只有當代碼必須是CLSCompliant時,纔會拋出此錯誤,但方法的主體在哪裏?或者換一種說法,我怎樣才能反映該方法的實際情況?

回答

5

這是一個虛擬的方法。據推測Type.GetField()正在返回一個派生的類型與真正的實現 - 嘗試打印info.GetType()。 (我剛剛在我的盒子上試過,例如System.RtFieldInfo。)

3

調試器顯示比testValue.GetType().GetField("MaxValue")返回的RtFieldInfo是從RuntimeFieldInfo派生出來的,派生自FieldInfo。所以這種方法最有可能被其中一個類覆蓋。最有可能的原因是FieldInfo對運行時類型和類型的反射式加載程序集有不同的實現方式

+0

Jon比平常要快,但你的結論等於他的;)。 – Abel 2012-03-29 14:37:32

相關問題