Родовая проблема наследования с использованием рефлексии - PullRequest
1 голос
/ 28 февраля 2011

вот моя проблема: Я изменяю структуру, разработанную в моей компании, и у нас есть функция, которая возвращает любые изменения в свойствах класса. Это структура в рамках:

namespace Fwk.Business.Entities

    public class BusinessEntity : IIdentifiable, ICloneableExt
    {
       ...
    }

    public class EntityList<BE> where BE : BusinessEntity, new()
    {
       ...
    }
}

и это типичное использование:

namespace Common.Business.Entities
{

    public class ImportFileEntity : Fwk.Business.Entities.BusinessEntity
    {
       ...
    }

    public class ImportFileList : Fwk.Business.Entities.EntityList<ImportFileEntity>
    {
    }

}

Fwk.Business.Entities. Он даже проверяет, является ли свойство самим экземпляром Fwk.Business.Entities.BusinessEntity и, если это так, рекурсивно вызывает метод GetChanges. Но моя проблема - когда у меня есть свойство, которое является экземпляром Fwk.Business.Entities.EntityList. Я хочу вызвать метод GetChanges каждого элемента, но не могу определить эти свойства EntityList <>. Я пробовал с

pi.GetValue(this, null).GetType().IsSubclassOf(typeof(EntityList<BusinessEntity>))

где pi - это элемент PropertyInfo, который идентифицирует проверяемое свойство, но возвращает false. Я также пробовал многие другие функции Type, такие как IsInstanceOfType и IsAssignableFrom, всегда получая значение false, где мне нужно значение true. Странно то, что если я проверяю определенный тип BusinessEntity, он работает:

pi.GetValue(this, null).GetType().IsSubclassOf(typeof(EntityList<ImportFileEntity>))

но, конечно, это неприемлемо, поскольку у меня может быть список ЛЮБОЙ BusinessEntity.

Может кто-нибудь помочь мне решить эту проблему?

Чем заранее за все ответы Алекс.

UPDATE: SLaks дал мне хороший ответ, и я закодировал это:

bool isEntityList = false;
Type thisType = (pi.GetValue(this, null) ?? new object()).GetType();
while (thisType != typeof(object) && !isEntityList)
    if (thisType.IsGenericType && thisType.GetGenericTypeDefinition() == typeof(EntityList<>))
        isEntityList = true;
    else
        thisType = thisType.BaseType;

// If property is a subclass of EntityList, invoke GetChanges method.
if (isEntityList)
{
    EntityList<BusinessEntity> elList = (EntityList<BusinessEntity>)pi.GetValue(this, null);
    foreach (BusinessEntity beEntity in elList)
        returnValue += beEntity.GetChanges(messageFormat, stopAtFirstDifference);
}

Но я получаю исключение при использовании

EntityList<BusinessEntity> elList = (EntityList<BusinessEntity>)pi.GetValue(this, null);

Ах! Я думаю, что моя проблема в C # 3.5 не принимает ковариацию (что-то новое для меня, и существует в 4.0). Поэтому мне пришлось выставить свойство со списком как BusinessEntities

В EntityList, где BE: BusinessEntity, new ()

public virtual List<BusinessEntity> ItemsAsBE
{
    get
    {
        List<BusinessEntity> returnValue = new List<BusinessEntity>(this.Items.Count);
        foreach (BusinessEntity item in this.Items)
            returnValue.Add(item);
        return returnValue;
    }
}

и в BusinessEntity

// If property is a subclass of EntityList, invoke GetChanges method.
if (isEntityList)
{
    foreach (BusinessEntity beEntity in thisType.GetProperty("ItemsAsBE").GetValue(pi.GetValue(this, null), null) as List<BusinessEntity>)
        returnValue += beEntity.GetChanges(messageFormat, stopAtFirstDifference);
}

Спасибо всем! Надеюсь, что это поможет кому-то в будущем!

1 Ответ

3 голосов
/ 28 февраля 2011

Вам нужно рекурсивно пройтись по базовым типам Type и найти тип, который IsGenericType и для которого GetGenericTypeDefinition() == typeof(EntityList<>)

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