2012-03-29 68 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

相关问题