我有以下类结构:
public class RelationBase : Entity
{
}
public class RelationURL : RelationBase
{
}
public class RelationBaseList<T> where T: RelationBase
{
public List<T> Collection { get; set; }
}
public class RelationURLList : RelationBaseList<RelationURL>
{
}
public class RefTest
{
public RelationURLList urlList { get; set; }
public RefTest()
{
urlList = new RelationURList();
urlList.Collection = new List<RelationUR>();
urlList.Collection.Add(new RelationUR());
}
}
通过反射,我得到一个RelationURLList的实例,我想把它转换为RelationBaseList<RelationBase>
。不幸的是,我只能将它投射到RelationBaseList<RelationURL>
RefTest obj = new RefTest();
PropertyInfo[] props = obj.GetType().GetProperties();
foreach (PropertyInfo prop in props)
{
object PropertyValue = prop.GetValue(obj, null);
object cast1 = PropertyValue as RelationBaseList<RelationURL>;
object cast2 = PropertyValue as RelationBaseList<RelationBase>;
}
在cast1中,我有预期的对象,但cast2为null。因为我不想从RelationBase转换到每个可能派生的类,所以我想使用第二个转换(cast2)。任何想法,如何获得对象,而不是转换为每个派生类型?
答案 0 :(得分:3)
你不能。
编译器无法验证您所做的事情是否合法。
如果RelationBaseList
是一个接口,您可以使用out
关键字标记泛型参数,以表示该接口仅允许检索来自该对象的数据。< / p>
但是,您的代码组织方式,编译器无法验证您是否尝试这样做:
case2.Add(new SomeOtherRelationObject());
并且泛型的全部意义是使类型安全的代码。
所以不,你做不到。
答案 1 :(得分:1)
你想用RelationBaseList.Collection 做什么?
如果您只想访问Collection的值而不是设置它们,那么使用接口可能是一种可能的解决方案:
public interface IRelationBaseList
{
IEnumerable<RelationBase> Collection { get; }
}
public class RelationBaseList<T> : IRelationBaseList where T : RelationBase
{
IEnumerable<RelationBase> IRelationBaseList.Collection
{
get { return Collection; }
}
public List<T> Collection { get; set; }
}
public class RelationURLList : RelationBaseList<RelationURL>
{
}
所以你可以这样做:
RefTest obj = new RefTest();
PropertyInfo[] props = obj.GetType().GetProperties();
foreach (PropertyInfo prop in props)
{
object PropertyValue = prop.GetValue(obj, null);
var relationBaseList = PropertyValue as IRelationBaseList;
foreach (var relationBase in relationBaseList.Collection)
{
// do something with it
}
}