Можно ли использовать отражение для создания экземпляров свойств базового класса объектов? - PullRequest
5 голосов
/ 18 июня 2010

Как это:

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

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

Кажется, что отражение намекает на ответ.

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

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

редактировать Я могу представить себе два правильных решения: приведенное выше, и какое-то ключевое слово, например 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();
    }
}

Ответы [ 2 ]

2 голосов
/ 18 июня 2010

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

1 голос
/ 18 июня 2010

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

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

Примечание: вам, вероятно, стоит взглянуть на генерацию кода (идея T4, поскольку она поставляется с 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);
    }
}
...