【问题标题】:Does inheritance in generics work the same way as concrete and abstract classes, InvalidCaseException泛型中的继承是否与具体和抽象类的工作方式相同,InvalidCastException
【发布时间】:2011-04-28 12:04:52
【问题描述】:

我有三个班级:PostPost<T>WallPost

Post 是一个抽象类,表示具有 nametextuser 等属性的博客文章。

第二个抽象类是Post<T>,它是post 的通用版本,所以我可以实现一个通用的GetChildren(T Post) 来获取post 的子级并构建一个层次列表。

第三类是具体的“WallPost”,它是针对用户个人资料的特定帖子。

public class WallPost : Post<WallPost>

最后是一个Member 类,其中包含WallPosts 的集合。


我编写了一个控件,它接收一组帖子并将其显示在树中。我对该控件的属性之一是

public IList<Post<Post>> Posts
        {
            get; set;
        }

(我使用泛型是因为我需要得到孩子,GetChildren(T Post))。我将 type 参数设置为 Post,因此它将接受从 post、wallpost、blogpost 等继承的任何类

现在我的问题是我想将IList&lt;WallPost&gt; 类型的用户集合IList&lt;WallPost&gt; 传递给函数,我收到此错误:

     Unable to cast object of type 'NHibernate.Collection.Generic.
PersistentGenericBag`1[BO.WallPost]'
 to type 'System.Collections.Generic.IList`1[BO.Post`1[BO.Post]]'.

我猜这是因为虽然你可以写 Post p = new WallPost() 这样的东西,但你不能有 List&lt;Post&gt; posts = new List&lt;WallPost&gt;()

无论如何,我完全感到困惑,我希望我说清楚了。

提前谢谢你

E

附:我使用 NHibernate,没有提到任何包。

【问题讨论】:

  • 伙计,您尝试传递的集合显然不是 IList。看异常,是一个NHibernate.Collection.Generic.PersistentGenericBag
  • Explicit Casting Problem 的可能重复项
  • 我注意到,但在我的代码中没有提到包或任何东西,都是 IList

标签: c# .net asp.net nhibernate generics


【解决方案1】:

您正在尝试以非类型安全的方式使用泛型协变。

如果你写会发生什么

List<WallPost> wallList = new List<WallPost>();
List<Post> pList = wallList;
pList.Add(new OtherPost());        //Not a WallPost!

您只能使用只读接口 (IEnumerable&lt;Post&gt;) 或数组。

【讨论】:

  • 问题是我只能使用 IList 因为 Nhibernate 框架。
  • 好的,我将WallPosts 转换为 Enumerable 'AsEnumerable' 并将控件中的 posts 属性的数据类型更改为 IEnumerable> 并得到错误'无法隐式转换类型'System. Collections.Generic.IEnumerable' 到 'System.Collections.Generic.IEnumerable> '
  • @Eitan:WallPost 不是 Post&lt;Post&gt;
  • 是的,但是 WallPost 继承了 Post,这真的令人困惑 :)
【解决方案2】:

您需要检查您的 NHibernate 映射。 NHibernate 将您的收藏视为一个袋子,而不是一个列表。

从 NHibernate 的角度来看,列表可能不是合适的选择。列表为您提供了对集合成员的基于索引的访问,但您的表中必须有一个列表索引列,以便 NHibernate 将其映射为列表。

您可能应该查看 NHibernate 集合映射选项并选择最适合您的情况(集合、包、列表等)的选项。

【讨论】:

  • 我正在使用自动映射器,所以我并没有真正接触映射文件或任何东西
  • 好吧,您需要检查您的映射设置。无论在做什么映射都是将您的收藏映射为一个包。
【解决方案3】:

为了工作,你可以使用:

public IList<Post<WallPost>> Posts
{
    get; set;
}

并在分配时进行强制转换:

bla.Posts = posts.Cast<Post<WallPost>>();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 2017-02-23
    • 2014-08-29
    • 1970-01-01
    • 2021-04-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多