mercredi 14 février 2018

Set private 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?





Aucun commentaire:

Enregistrer un commentaire