Можно ли использовать отражение для создания экземпляра свойств базового класса объектов?

Нравится:

    public class remoteStatusCounts : RemoteStatus 
{
    public int statusCount;

    public remoteStatusCounts(RemoteStatus r)
    {
        Type t = r.GetType();
        foreach (PropertyInfo p in t.GetProperties())
        {
            this.property(p) = p.GetValue(); //example pseudocode
        }
    }
}

Пример немного прост (он взят из Jira API - RemoteStatus имеет 4 свойства), но представьте, что базовый класс имеет 30 свойств. Я не хочу вручную устанавливать все эти значения, особенно если у моего унаследованного класса есть только несколько дополнительных свойств.

Размышления как бы намекают на ответ.

Я видел в Использование наследования в конструкторе (publix X (): y), что Я могу вызвать конструктор базового класса (я думаю? Поправьте меня, если я ошибаюсь), но у моего базового класса нет конструктора - он унаследован от jira wsdl

        public remoteStatusCounts(RemoteStatus r) : base(r) { //do stuff }

edit Я могу представить 2 действительных решения: одно, описанное выше, и какое-то ключевое слово, например this.baseClass, которое имеет значение type(baseclass) и которым манипулируют как таковые, действуя как своего рода указатель на this. Итак, this.baseClass.name = "Johnny" будет тем же самым, что и this.name = "Johnny"

Для всех намерений и целей предположим, что базовый класс имеет конструктор копирования, то есть это допустимый код:

        public remoteStatusCounts(RemoteStatus r) {
            RemoteStatus mBase = r;
            //do work
        }

edit2 Этот вопрос скорее является мысленным упражнением, чем практическим - для моих целей я мог бы так же легко сделать это: (при условии, что мой "базовый класс" может делать копии)

    public class remoteStatusCounts 
{
    public int statusCount;
    public RemoteStatus rStatus;
    public remoteStatusCounts(RemoteStatus r)
    {
        rStatus = r;
        statusCount = getStatusCount();
    }
}

person scaryman    schedule 18.06.2010    source источник
comment
Или генерация кода, но я бы не пошел по этому пути.   -  person scaryman    schedule 18.06.2010
comment
Примечание: имена ваших классов должны начинаться с заглавной буквы. </code-format-nazi>   -  person Aren    schedule 19.06.2010


Ответы (2)


Да, вы можете это сделать, но имейте в виду, что вы можете столкнуться со свойствами только для получения, с которыми вам придется иметь дело отдельно.

Вы можете отфильтровать его с помощью перегрузки Type.GetProperties(BindingsFlags).

Примечание: вам, вероятно, следует изучить генерацию кода (идея T4, поскольку она поставляется с vs 2008/2010), потому что отражение может иметь последствия во время выполнения, такие как скорость выполнения. С помощью генерации кода вы можете легко справиться с этой утомительной работой и по-прежнему иметь ту же среду выполнения и т. Д., Например, вводя ее вручную.

Пример:

//extension method somewhere
public static T Cast<T>(this object o)
{
    return (T)o;
}

public remoteStatusCounts(RemoteStatus r)
{
    Type typeR = r.GetType();
    Type typeThis = this.GetType();

    foreach (PropertyInfo p in typeR.GetProperties())
    {
        PropertyInfo thisProperty = typeThis.GetProperty(p.Name);

        MethodInfo castMethod = typeof(ExMethods).GetMethod("Cast").MakeGenericMethod(p.PropertyType);
        var castedObject = castMethod.Invoke(null, new object[] { p.GetValue(r, null) });
        thisProperty.SetValue(this, castedObject, null);
    }
}
person Femaref    schedule 18.06.2010
comment
Как? Я не могу вызвать setValue для объектов .. this.setValue (p.Name, r.getValue) не компилируется. - person scaryman; 19.06.2010
comment
Вы, конечно, должны получить для этого объект Type, получить соответствующее свойство с помощью t.GetProperty (name) и выполнить SetValue для этого объекта. - person Femaref; 19.06.2010
comment
Он компилируется следующим образом: thisProperty.SetValue (this, p.GetValue (typeR, null), null); Но затем он выдает исключение времени выполнения. Объект не соответствует целевому типу. - person scaryman; 19.06.2010
comment
Неа. Невозможно вызвать getType () для статических классов. +1 за приближение. - person scaryman; 19.06.2010
comment
Исключение времени выполнения - TargetException не было обработано пользовательским кодом - объект не соответствует целевому типу. Спасибо, что поработали над этим - я действительно ничего не знаю об отражении. Я подумал, что это должно быть возможно, хотя понятия не имею. - person scaryman; 21.06.2010
comment
фиксированный. протестировал, это должно работать. p.GetValue был неправильным - он пытался получить значение для объекта типа, что, очевидно, потерпело неудачу. - person Femaref; 21.06.2010
comment
stackoverflow.com/ questions / 1198886 / - вопрос аналогичный. - person scaryman; 21.06.2010

Попробуйте AutoMapper.

person Jordão    schedule 18.06.2010
comment
Сладкий! Я никогда не слышал об этом раньше - это обязательно когда-нибудь пригодится! - person scaryman; 18.06.2010