2011-02-28 15 views
1

这里是我的问题: 我正在修改我公司开发的框架,并且我们有一个函数返回类属性中的任何更改。 这是在框架结构:使用反射的泛型继承问题

namespace Fwk.Business.Entities 

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

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

,这是一个使用tipical:

namespace Common.Business.Entities 
{ 

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

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

} 

Fwk.Business.Entities.BusinessEntity具有如下功能命名GetChanges(),通过所有使用反射迭代属性并检查它们是否改变了它们的值(使用原始BusinessEntity的副本)。它甚至检查该属性本身是否是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,在我需要true的地方总是会出现错误。 奇怪的是,如果我检查特定的BusinessEntity类型,它的工作:

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

,但当然这是不能接受的,因为我可以有任何的BusinessEntity的列表。

任何人都可以帮我解决这个问题吗?

比所有的回复 亚历克斯。

UPDATE: SLaks给了我一个很好的回答,我这个编码:做

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

阿当

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

但我发现了一个转换异常!我认为我的问题是C#3.5不接受协变(对我来说是新东西,而在4.0中是存在的)。所以我不得不暴露与列表中的财产BusinessEntities

在EntityList在哪里:BusinessEntity的,新的()

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

谢谢大家!希望这有助于未来的人!

+0

而当属性为类型的BusinessEntity []是什么呢? – SWeko 2011-02-28 15:12:34

+0

不需要担心,因为我们“训练有素”使用相应的“List”类。尽管感谢您的领导。 – Alex 2011-02-28 16:52:49

回答

3

您需要通过Type的基本类型递归循环,并寻找一个类型的IsGenericType和其GetGenericTypeDefinition() == typeof(EntityList<>)

+0

非常感谢,SLaks,这个工作!但我现在遇到了另一个问题...请参阅上面的我的编辑 – Alex 2011-02-28 16:19:32