【问题标题】:Is it possible to use a list of untyped generics in C#?是否可以在 C# 中使用无类型泛型列表?
【发布时间】:2010-08-31 23:06:22
【问题描述】:

我正在尝试以下设计但没有成功:

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

class Bar
{
    List<Foo> Foos;
}

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

正如我目前的代码一样,我使用无类型的 Foo 和 Output 作为对象。

【问题讨论】:

标签: c# generics list


【解决方案1】:

如果我对您的理解正确,您想要一个具有不同类型 Outputs 的 Foo 对象列表,对吗?由于这些输出具有不同的类型,因此无论如何您都必须在此处使用强制转换。

但是,以下想法可能会有所帮助。你如何声明一个名为IFoo 的非泛型接口:¹

public interface IFoo
{
    object Output { get; }
}

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

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

然后可以声明IFoos的列表:

class Bar
{
    List<IFoo> Foos;
}

访问这些 foo 时,您可以通过接口将输出作为对象检索:

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&lt;T&gt;。在这种情况下,您需要使用 new 关键字标记 Foo&lt;T&gt;.Output 并使用 base.Output 访问抽象基成员。

【讨论】:

  • 谢谢。 :) 正是我想要的。
【解决方案2】:

List&lt;Foo&gt; 无效,因为 Foo 是一个模板,需要指定一个类,即使它本身又是一个泛型 (List&lt;Foo&lt;U&gt; &gt;)。

【讨论】:

  • 就是这样。使 Bar 通用(类型参数也可以是 T,或 U,或其他)并使用类型参数来保持 Foo 处于打开状态。您可以在您可以控制的容器层次结构中执行此操作;但是,在某些时候,您必须使用具体类型关闭通用实现才能使用类。如果你想动态地做到这一点,你可以使用反射来实例化一个封闭的通用对象,该对象由 Type 对象或字符串标识,但这很快就会变得混乱。
【解决方案3】:

不,您不能以这种方式使用泛型。您需要向Bar 添加一个泛型类型参数并将其转发给Foo&lt;T&gt;,或者在Bar 类型中提供Foo&lt;T&gt; 的封闭实例。

第一个例子

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

【讨论】:

  • 我想他知道这一点。他不是这个意思。
  • @Timwi,那么问题中的 OP 应该更清楚。当面对一个模棱两可的问题时,很容易给出错误的答案。对我和其他人投反对票是没有根据的。按照你的逻辑,我应该反对你的解释与我不同。
  • 我同意,我也觉得这种模棱两可的问题很烦人。很容易假设自己的解释是正确的——对此感到抱歉! (当然,如果@Lazlo 对此有所了解会有所帮助...)(不过,GameZelda 似乎同意我的观点 :))
  • 抱歉不清楚,尽管我无法解释为什么 JaredPar 可能认为我需要知道这一点。我的问题确实是 Timwi 如何解释它。
猜你喜欢
  • 1970-01-01
  • 2013-03-01
  • 2023-04-11
  • 2020-06-28
  • 1970-01-01
  • 1970-01-01
  • 2011-08-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多