通过反思

时间:2018-02-14 16:35:42

标签: c# reflection c#-7.2

我知道这有几个规范的答案(我过去成功使用过!)请参阅https://stackoverflow.com/a/1778410/1675729https://stackoverflow.com/a/1565766/1675729。作为参考,这些方法涉及在属性的SetValue上使用PropertyInfo方法,或者使用反射调用setter方法,或者在极端情况下,直接设置支持字段。但是,现在这些方法似乎都不适合我,而且我很好奇是否有某些内容已经破坏了这个功能。

请考虑以下事项:

using System;
using System.Reflection;

public class Program
{
    public static void Main()
    {
        var exampleInstance = new Example();
        var exampleType = typeof(Example);
        var fooProperty = exampleType.GetProperty("Foo"); // this works fine - the "GetSetMethod" method returns null, however

        // fails with the following:
        // [System.MethodAccessException: Attempt by method 'Program.Main()' to access method 'Example.set_Foo(Int32)' failed.]
        //fooProperty.SetValue(exampleInstance, 24);

        // same error here:
        //Run-time exception (line 14): Attempt by method 'Program.Main()' to access method 'Example.set_Foo(Int32)' failed.
        //exampleType.InvokeMember(fooProperty.Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.SetProperty | BindingFlags.Instance, null, exampleInstance, new object[] { 24 });
    }
}

public class Example 
{
    public int Foo { get; private set; }
}

Foo属性一个setter,它只是私有的。如果我将setter更改为 protected ,它也会失败,这似乎更奇怪,因为它不再是仅限C#6初始化程序的setter。这与.NET 4.5和.NET Core 2都作为运行时失败。我错过了什么?

2 个答案:

答案 0 :(得分:1)

此行为是设计使然。 有一些严格的规则可以控制以这种方式滥用反射的能力。

Accessing Members That Are Normally Inaccessible

事实上,如果您打算使用反射,在现实生活中,整篇文章可能值得一读。 Security Considerations for Reflection

答案 1 :(得分:1)

我遇到了类似的问题(除了我使用的是静态属性),而且我能够像这样调用私有设置器:

public static class Example 
{
    public static int Foo { get; private set; }
}

typeof(Example).GetProperty("Foo").SetMethod.Invoke(null, new object[] { 42});

虽然没有经过非静态测试。