Как метод может содержать только NotImplementedException и все еще работать без выброса? - PullRequest
2 голосов
/ 29 марта 2012

Если я отмечу в Reflector значение FieldInfo.SetValueDirect, оно выглядит следующим образом:

C #, .NET 4.0:

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

И как ИЛ:

.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 , но где находится тело метода? Или, другими словами, как я могу отразить фактическое тело метода?

Ответы [ 2 ]

5 голосов
/ 29 марта 2012

Это виртуальный метод. Предположительно Type.GetField() возвращает производный тип с реальной реализацией - попробуйте напечатать info.GetType(). (Я только что попробовал свою коробку, и она показала System.RtFieldInfo, например.)

3 голосов
/ 29 марта 2012

Отладчик показывает, что testValue.GetType().GetField("MaxValue") возвращает RtFieldInfo, который получен из RuntimeFieldInfo, который получен из FieldInfo. Так что, скорее всего, этот метод был переопределен в одном из этих классов. Скорее всего, потому что реализация FieldInfo для типов и типов во время выполнения отличается от загруженных сборок только для отражения

...