很难拿到一个好头衔,但让我说我有这种情况。我有一个基类:
public abstract class FooBase
{
}
我有一个通用的实现:
public class MyFoo<T> : FooBase where T : Bar
{
}
到目前为止一切顺利。抽象基础是这样我可以创建这些通用项的异构集合:
List<FooBase> list = new List<FooBase>()
{
new MyFoo<Bar1>(),
new MyFoo<Bar2>()
}
现在问题来了。我有一个通用的方法:
public void DoSomething<T>(MyFoo<T> aFoo) where T : Bar
{
}
当我使用特定 Foo
的实例调用它时,此功能正常工作:
DoSomething(new MyFoo<Bar1>());
但是我想要一个能够获取列表并在每个项目上调用DoSomething
的函数:
public void DoSomethingWithList(List<FooBase> list)
{
foreach (var item in list)
{
DoSomething(item); // doesn't work - type cannot be inferred here
}
}
那么有没有办法在运行时让它找出正确的类型并调用泛型函数?还是有其他方法摆脱这个难题?
答案 0 :(得分:5)
您可以使用动态类型 - 它将在执行时使用item
引用的对象的实际类型执行重载解析。您只需将迭代器类型更改为dynamic
,如下所示:
public void DoSomethingWithList(List<FooBase> list)
{
foreach (dynamic item in list)
{
DoSomething(item);
}
}
请注意,如果您的列表中的FooBase
最终不是 MyFoo<T>
,则会导致执行时间失败。您可以通过提供另一个重载来避免(如果您愿意):
public void DoSomething(FooBase x)
{
// This will be called for any items in the list that aren't
// MyFoo<T>
}
这种方法的缺点:
dynamic
被引入的时候。如果可以通过重新设计来避免陷入这种情况,那通常是一个好主意......但有时你确实需要这样的东西。
答案 1 :(得分:0)
不,因为必须在编译时知道泛型类型,并且您的示例不向编译器提供信息,他应该使用什么类型,您必须在方法调用中手动插入类型