【问题标题】:Casting to a generic base type转换为通用基类型
【发布时间】:2013-12-17 11:10:43
【问题描述】:

我有以下类结构:

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&lt;RelationBase&gt;。不幸的是,我只能将其转换为RelationBaseList&lt;RelationURL&gt;

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 为空。由于我不想从 RelationBase 转换为每个可能的派生类,我想使用第二个转换 (cast2)。任何想法,我如何获取对象,而不转换为每个派生类型?

【问题讨论】:

    标签: c# generics reflection casting


    【解决方案1】:

    你不能。

    编译器无法验证您所做的是否合法。

    如果RelationBaseList 是一个接口,您可以用out 关键字标记泛型参数,以表明该接口只允许检索对象中的数据。

    但是,根据您的代码组织方式,编译器无法验证您没有尝试这样做:

    case2.Add(new SomeOtherRelationObject());
    

    而泛型的全部意义在于使代码类型安全

    所以不,你不能那样做。

    【讨论】:

      【解决方案2】:

      您想用 RelationBaseList.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
          }
      }
      

      【讨论】:

      • 我只想解析集合,所以您的解决方案非常适合我!非常感谢! :)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-13
      • 2017-09-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多