【问题标题】:How can a method contain only a NotImplementedException and still run without throwing?一个方法如何只包含一个 NotImplementedException 并且仍然运行而不抛出?
【发布时间】:2012-03-29 14:11:42
【问题描述】:

如果我检查 FieldInfo.SetValueDirect 的反射器,它看起来如下:

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 时才会抛出此问题,但是方法的主体在哪里?或者,换一种说法,我如何才能反映方法的实际主体?

【问题讨论】:

    标签: c# reflection notimplementedexception


    【解决方案1】:

    这是一个虚方法。大概Type.GetField() 正在返回一个具有实际实现的派生 类型——尝试打印info.GetType()。 (我刚刚在我的盒子上试了一下,它显示了System.RtFieldInfo。)

    【讨论】:

      【解决方案2】:

      调试器显示比testValue.GetType().GetField("MaxValue") 返回的RtFieldInfo 派生自从FieldInfo 派生的RuntimeFieldInfo。所以很可能这个方法在这些类之一中被覆盖了。很可能是因为运行时类型和仅反射加载程序集的类型有不同的 FieldInfo 实现

      【讨论】:

      • 乔恩像往常一样比光快,但你的结论和他的一样;)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-09
      • 2011-09-18
      • 2022-01-24
      • 1970-01-01
      • 1970-01-01
      • 2016-09-06
      • 1970-01-01
      相关资源
      最近更新 更多