理解泛型与继承类的结合

时间:2011-01-28 15:18:21

标签: c# abstract-class generics

这是与NHibernate相关的another one I asked相关问题,但我开始认为我的问题可能远不止于此。

对于NHibernate相关的原因,我有一个基本抽象类(Listing)和从它继承的类(Listing_UKListing_US等)。 /> 这些在功能上是相同的 我理解为什么这不起作用:

List<Listing> test = new List<Listing_UK>();

现在我正在做相同的事情:

List<Listing> test = new List<Listing>();
test.Add(new Listing_UK() as Listing);

哪个有效,但是我需要这些类更加可互换,如上所述。

我很欣赏我所做的基本理念有点奇怪,但有人有什么建议吗?

编辑:

我显然让我的例子过于抽象 我试图避免使这个NHibernate具体化,以便它实际上与我的其他问题不同(因为我认为我所要求的是更基本的),但我基本上想要实现的是:< / p>

IQueryOver<Listing,Listing> test = null;
if(condition) {
  test = DBSession.QueryOver<Listing_UK>();
} else {
  test = DBSession.QueryOver<Listing_US>();
}
test.Where(l => l.Field == "value").List<Listing>();

从我到这里的反应来看,我有理由相信我所要求的是不可能的。

3 个答案:

答案 0 :(得分:1)

您无需在代码中使用“as”。这样可以正常工作:

List<Listing> test = new List<Listing>();
test.Add(new Listing_UK());

你还不清楚你不能做什么。你真的需要List<Listing_UK>吗?这里的大局是什么?如果您可以显示一些不起作用的代码,那将有所帮助。

编辑:好的,既然你已经解释了一下,我怀疑你想要一个通用的方法:

List<Listing> list = condition ? QueryList<Listing_UK>() 
                               : QueryList<Listing_US>();

private static List<Listing> QueryList<T>() where T : Listing
{
    return DBSession.QueryOver<T>()
                    .Where(l => l.Field == "value")
                    .List<Listing>();
}

我不太清楚NHibernate知道这是否足够,但如果不是,我确定你可以稍微调整一下。

你原本想要只是试图互换地处理这些类型的想法真的不会起作用。

答案 1 :(得分:0)

如果Listing_UK继承自抽象类Listing,则在将其添加到List时不需要进行任何转换。像这样的堕落是隐含的。

List<Listing> test = new List<Listing>();
test.Add(new Listing_UK());

然后,当你想要处理每个清单时,你只需要处理它们的类型。

foreach (Listing listing in test)
{
    listing.Update();
    if (listing is Listing_UK)
        ((Listing_UK)listing).PunchTheQueen();
}

简单!

答案 2 :(得分:0)

class Foo : Bar { }

void Test(List<Bar> list);

请记住,你可以这样做:

List<Bar> list = new List<Bar>();
Test (list);

但你不能:

List<Foo> list = new List<Foo>();
Test (list);

要实现这一目标,请使用:

void Test2 <T> (List<T> list) where T : Bar    

List<Foo> list = new List<Foo>();
Test (list.Cast<Bar>().ToList()); // not ToList<Bar>()

那是因为

Bar is Bar; // true
Foo is Bar; // true
List<Foo> is List<Foo>; // true
List<Bar> is List<Bar>; // true

List<Foo> is List<Bar>; // false!