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

Как указано в .NET Reflection set private property, можно установить свойство с помощью частного сеттера . Но когда свойство определено в базовом классе, выдается 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);
    }
}

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

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


person tafa    schedule 06.04.2012    source источник


Ответы (4)


У меня была аналогичная проблема, когда моя частная собственность была объявлена ​​​​в базовом классе. Я использовал 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);
    }
}
person Paul Bullivant    schedule 19.09.2013

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

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

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

ИЗМЕНИТЬ:

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

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

typeof(Derived ).GetProperties().Contains(p=>p.Name == "whatever")
person Not loved    schedule 06.04.2012
comment
Это определенно сработало бы, если бы базовый тип был известен. Пожалуйста, смотрите мое редактирование. - person tafa; 06.04.2012

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

typeof(Derived)
    .BaseType.GetProperty("ModifiedOn")
    .SetValue(p, DateTime.Today, null);
person Adrian Iftode    schedule 06.04.2012
comment
Да, если дерево наследования имело длину один. Пожалуйста, смотрите мое редактирование. - person tafa; 06.04.2012
comment
Затем вы идете по линии... Вы можете остановиться на System.Object. - person Henk Holterman; 06.04.2012

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

    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;
        }
    }
person keza    schedule 01.08.2013