通过反射设置属性的私有setter方法

7
我知道这个问题有几个标准答案(我以前成功使用过!)请参见https://dev59.com/d3I-5IYBdhLWcg3wlpeW#1778410https://dev59.com/eXI_5IYBdhLWcg3wAeLl#1565766。这些方法涉及使用属性的PropertyInfoSetValue方法,否则使用反射调用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 运行时中都会失败。我错过了什么吗?


私有还是公共?你的例子展示了一个公共属性,而你的问题问的是一个私有属性。 - Gusman
3
我有点困惑,上面的代码对我来说运行得很好。Example 类是在另一个程序集中吗? - DavidG
你是否正在运行部分受信任的代码? - user6144226
不,我正在运行与我在问题中提供的完全相同的代码。请跟随我在评论中提供的dotnetfiddle链接以查看它抛出异常。 - NWard
1
@NWard 对我来说,在线编译器没有完全信任运行似乎是很合理的。就这个链接而言,这似乎是预期的行为 https://learn.microsoft.com/en-us/dotnet/framework/reflection-and-codedom/security-considerations-for-reflection#accessingNormallyInaccessible - user6144226
显示剩余7条评论
2个回答

2

我遇到了类似的问题(不同之处在于我使用的是静态属性),我可以通过以下方式调用私有 setter:

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

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

我还没有测试过非静态的情况。

这就是静态属性的全部内容,这正是我所需要的。谢谢。 - Francesco B.

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接