繁体   English   中英

转换为通用基本类型

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM