Подтвердить что ты не робот

Метод набора свойств не найден в производном типе

Как описано в .NET Reflection задает частное свойство, можно установить свойство с помощью частного сеттера. Но когда свойство определено в базовом классе, вызывается System.ArgumentException: "Метод набора свойств не найден".

Примером может быть:

using System;
class Test
{
    public DateTime ModifiedOn { get; private set;}
}

class Derived : Test
{
}

static class Program
{
    static void Main()
    {
        Derived p = new Derived ();
        typeof(Derived).GetProperty("ModifiedOn").SetValue(
            p, DateTime.Today, null);
        Console.WriteLine(p.ModifiedOn);
    }
}

Кто-нибудь знает, как справиться с этой ситуацией?

Изменить: Приведенный пример является простой иллюстрацией проблемы. В сценарии реального мира я не знаю, определено ли свойство в базовом классе или определено в базе базового класса.

4b9b3361

Ответ 1

У меня была аналогичная проблема, когда моя частная собственность была объявлена ​​в базовом классе. Я использовал DeclaringType, чтобы получить дескриптор класса, в котором определено свойство.

using System;
class Test
{
    public DateTime ModifiedOn { get; private set;}
}

class Derived : Test
{
}

static class Program
{
    static void Main()
    {
        Derived p = new Derived ();

        PropertyInfo property = p.GetType().GetProperty("ModifiedOn");
        PropertyInfo goodProperty = property.DeclaringType.GetProperty("ModifiedOn");

        goodProperty.SetValue(p, DateTime.Today, null);

        Console.WriteLine(p.ModifiedOn);
    }
}

Ответ 2

Я думаю, что это сработает:

using System;
class Test
{
    public DateTime ModifiedOn { get; private set;}
}

class Derived : Test
{
}

static class Program
{
    static void Main()
    {
        Derived p = new Derived ();
        typeof(Test).GetProperty("ModifiedOn").SetValue(
            p, DateTime.Today, null);
        Console.WriteLine(p.ModifiedOn);
    }
}

Вам нужно получить определение свойства из класса, на котором он фактически определен не на производном классе

EDIT:

Чтобы выбрать его в любом базовом классе, вам нужно будет искать его на всех родительских классах.

что-то вроде этого, а затем возвратитесь к базовому классу, пока вы не нажмете объект или не найдете свое свойство

typeof(Derived ).GetProperties().Contains(p=>p.Name == "whatever")

Ответ 3

Другим вариантом, чем @LukeMcGregor, является использование BaseType

typeof(Derived)
    .BaseType.GetProperty("ModifiedOn")
    .SetValue(p, DateTime.Today, null);

Ответ 4

Я сделал этот метод многократного использования. Он обрабатывает мои сценарии.

    private static void SetPropertyValue(object parent, string propertyName, object value)
    {
        var inherType = parent.GetType();
        while (inherType != null)
        {
            PropertyInfo propToSet = inherType.GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance);
            if (propToSet != null && propToSet.CanWrite)
            {
                propToSet.SetValue(parent, value, null);
                break;
            }

            inherType = inherType.BaseType;
        }
    }