将C#中的Foo<Bar>强制转换为Foo<object>

8

有没有人知道是否可以将具有特定类型参数(例如Bar)的通用类型转换为具有Bar基类型的类型参数(在我的情况下为object)的同一通用类型。如果可能,如何实现?

我想做的是拥有Foo<object>的集合,但能够添加具有更具体类型参数的Foos。

谢谢


2
将来参考,这被称为协变性。C# 4为接口和委托提供了此功能。 - R. Martinho Fernandes
请参见https://dev59.com/rHVC5IYBdhLWcg3wlyMo。 - Cheeso
@Reed:看起来Michael想要将Foo<Bar>添加到Collection<Foo<Object>>中。这需要C# 4的协变性支持。 - Roman Boiko
1
@Roman:嗯...如果是这样,就需要协变性。不太清楚,因为没有显示代码。不过我最初的理解不是这样的。 - Reed Copsey
3
@Reed:文本中缺少一个单引号。 - Eric Lippert
显示剩余3条评论
4个回答

3
您可以创建一个包含基本类型和子类的集合。例如,以下代码是可行的:
// Using:
public class Foo {} // Base class
public class Bar : Foo {} // Subclass

// Code:
List<Foo> list = new List<Foo>();
HashSet<Foo> hash = new HashSet<Foo>();

list.Add(new Bar());
list.Add(new Foo());

hash.Add(new Bar());

"Bar"是"Foo"的一种特定类型,因此将其添加到Foo集合中是完全合法的。

然而,在.NET 4之前和使用协变的out修饰符之前,您无法执行以下操作:

IEnumerable<Foo> list = new List<Bar>(); // This isn't supported in .NET 3.5...

5
实际上,在.NET 4中你也不能这样做。因为在IList<T>中,T既出现在参数中(Add方法),又出现在返回值中(索引器),所以既不是协变也不是逆变的。但是在IEnumerable<T>中可以实现。 - R. Martinho Fernandes

2

1
他并没有给出任何具体细节。即使你需要从一个集合转换到另一个集合,ConvertAll函数、List(T)或Array在这些情况下也非常方便。 - vfilby

2

在C# 4.0中是可以实现的!

您应该了解协变性


1
这不是正确的。你应该说“是的,从C# 4开始是可能的”。 - R. Martinho Fernandes
从技术上讲,在C# 4中它并不真正可用,因为你只能在接口和委托上具有协变性,而不能在一般类型上。 - jbtule


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接