2010-08-31 64 views
6

我想下面的设计没有成功:是否有可能在C#中使用无类型的泛型列表?

abstract class Foo<T> 
{ 
    abstract T Output { get; } 
} 

class Bar 
{ 
    List<Foo> Foos; 
} 

我不喜欢使用数组列表,因为我将不得不使用不安全的强制类型转换来获取类型。我希望输入Foo,以便“输​​出”不只是一个对象,在这种情况下,我也必须使用不安全的强制转换。

由于我的代码是在这个时候,我用Foo作为一个对象与输出无类型。

+0

完全重复:http://stackoverflow.com/questions/353126/c-multiple-generic-types-in-one-list – GameZelda 2010-09-01 01:30:56

回答

8

的例如,如果我理解正确的话,你希望它有不同类型的Output小号Foo对象的列表,对不对?由于这些输出具有不同的类型,因此无论如何您都必须使用强制转换。

但是,下面的想法可能会有所帮助。你怎么样声明一个名为IFoo非通用接口:¹

public interface IFoo 
{ 
    object Output { get; } 
} 

,然后实现它在你的抽象类:

abstract class Foo<T> : IFoo 
{ 
    abstract T Output { get; } 
    object IFoo.Output { get { return Output; } } 
} 

然后你就可以申报IFoo个清单:

class Bar 
{ 
    List<IFoo> Foos; 
} 

访问这些foos时,您可以通过界面检索输出为对象:

var myObject = Foos[0].Output;  // type ‘object’ 

,或者你可以尝试去发现真正的类型,如果你知道它只能是一些特定类型之一:

if (Foos[0] is Foo<string>) 
    var myString = ((Foo<string>) Foos[0]).Output; // type ‘string’ 

你甚至可以做基于类型过滤,例如:

// Type ‘IEnumerable<string>’ (rather than ‘IEnumerable<object>’)! 
var stringFoos = Foos.OfType<Foo<string>>().Select(f => f.Output); 

¹您也可以让这个所谓的Foo抽象基类和具有Foo<T>从中获得。在这种情况下,您需要使用new关键字标记Foo<T>.Output,并使用base.Output访问抽象基础成员。

+0

谢谢。 :)正是我在找什么。 – Lazlo 2010-09-01 17:54:02

0

List<Foo>无效,因为Foo是一个模板,需要指定的类,即使它再次是通用本身(List<Foo<U> >)。

+0

泛型不是模板... – 2010-08-31 23:29:35

+0

这将是它。使Bar成为通用的(类型参数也可以是T,或U或其他),并使用type参数来保持Foo打开。您可以根据您的控制尽可能远地完成容器层次结构;然而,在某些时候,你必须用一个具体的类型来关闭泛型实现,以便使用类(es)。如果你想动态地做到这一点,你可以使用反射来实例化一个通用对象,该通用对象被一个Type对象或一个字符串所标识的类型关闭,但是这会很快变得混乱。 – KeithS 2010-08-31 23:32:14

0

不,您不能以这种方式使用泛型。您需要将通用类型参数添加到Bar并将其转发给Foo<T>或在Bar类型中提供Foo<T>的已关闭实例。

第一

class Bar<T> { 
    public List<Foo<T>> Foos; 
} 
+1

我想他知道这一点。这不是他的意思。 – Timwi 2010-08-31 23:36:58

+1

@Timwi,那么OP应该在问题中更清楚。当面对一个模棱两可的问题时,很容易给出一个不正确的答案。对我和其他人的低估是毫无根据的。根据你的逻辑,我应该低估你对我的解释。 – JaredPar 2010-08-31 23:51:47

+0

我同意,我也发现这样含糊不清的问题。假设一个人自己的解释是正确的 - 很抱歉! (当然,如果@Lazlo对此有所了解,这将有所帮助......)(GameZelda似乎同意我的观点,尽管:)) – Timwi 2010-09-01 10:36:46

相关问题