通过反射在属性上设置私有设置器

Posted

技术标签:

【中文标题】通过反射在属性上设置私有设置器【英文标题】:Set private setter on property via reflection 【发布时间】:2018-07-25 07:29:41 【问题描述】:

我知道这有几个规范的答案(我过去曾成功使用过!)请参阅 https://***.com/a/1778410/1675729 和 https://***.com/a/1565766/1675729。作为参考,这些方法包括在属性的PropertyInfo 上使用SetValue 方法,或者通过反射调用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 作为运行时,这将失败。我错过了什么?

【问题讨论】:

私人还是公共?您的示例显示了公共属性,而您的问题询问的是私有属性。 属性是公共的,setter是私有的。我将澄清我的问题标题。 我有点困惑,上面的代码对我来说很好用。 Example 类是否在不同的程序集中? 我也很困惑,因此提出了这个问题。试试看:dotnetfiddle.net/o4JtEq @NWard 对我来说,在线编译器没有完全信任运行似乎很合乎逻辑。就这个链接而言,这似乎是预期的行为docs.microsoft.com/en-us/dotnet/framework/… 【参考方案1】:

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

public static class Example 

    public static int Foo  get; private set; 


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

但尚未使用非静态测试。

【讨论】:

这就是静态属性,这是我正在寻找的。谢谢【参考方案2】:

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

Accessing Members That Are Normally Inaccessible

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

【讨论】:

以上是关于通过反射在属性上设置私有设置器的主要内容,如果未能解决你的问题,请参考以下文章

Java反射设置和访问私有属性值

反射学习3-通过反射机制修改类中的私有属性的值

有没有办法使用反射类设置私有/受保护的静态属性?

缓存反射属性获取器/设置器的最佳方法?

面向对象,封装,反射,绑定方法

Java通过反射可以设置私有变量的好处有哪