[英]Casting to a generic base type
我具有以下类结构:
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)。 任何想法,如何在不强制转换为每个派生类型的情况下获取对象?
你不能
编译器无法验证您所做的合法。
如果RelationBaseList
是接口,则可以使用out
关键字标记通用参数,以表明该接口仅允许从对象中检索数据。
但是,按照代码的组织方式,编译器无法验证您是否尝试执行此操作:
case2.Add(new SomeOtherRelationObject());
而泛型的全部重点是制作类型安全的代码。
所以不,你不能那样做。
您想对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
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.