简体   繁体   中英

Set private setter on property via reflection

I know this has several canonical answers (that I've used successfully in the past!) See https://stackoverflow.com/a/1778410/1675729 and https://stackoverflow.com/a/1565766/1675729 . For reference, these methods involve using the SetValue method on the PropertyInfo of the property, or otherwise invoking the setter method with reflection, or in extreme cases, setting the backing field directly. However, none of these methods seem to be working for me now, and I'm curious if something has changed that has broken this functionality.

Consider the following:

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; }
}

The Foo property has a setter, it's just private. It also fails if I change the setter to protected , which seems even more bizarre, since it's no longer the C#6 initializer-only setter. This fails with both .NET 4.5 and .NET Core 2 as the runtime. What am I missing?

This behaviour is by design. There are some strict rules that govern the ability to abuse reflection in this way.

Accessing Members That Are Normally Inaccessible

In fact if you plan on using reflection at all, in a real life secnario the entire article might be worth a read. Security Considerations for Reflection

I was having a similar issue (with the exception that I'm using a static property) and I was able to invoke private setter like this:

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

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

Haven't tested with non-static though.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM