我有一个具有此签名的Matrix类:
public partial struct Matrix : IEnumerable<Vector>, IEquatable<Matrix> { ... }
然后,类似地,我有一个Vector类:
public partial struct Vector : IEnumerable<float>, IEquatable<Vector> { ... }
所以,代码中的其他地方,我有:
Matrix matrix = new Matrix();
IEnumerable<IEnumerable<float>> floatEnumerationEnumeration = matrix;
但它无法编译,说它无法将Matrix
转换为IEnumerable<IEnumerable<float>>
。
但我不知道为什么不呢?
答案 0 :(得分:1)
Matrix
实施IEnumerable<Vector>
但不IEnumerable<IEnumerable<float>>
。让它实现IEnumerable<IEnumerable<float>>
或者将其转换为正确的类型:
IEnumerable<IEnumerable<float>> floatEnumerationEnumeration =
matrix.Cast<IEnumerable<float>>();
请注意,如果B
来自A
,那么这并不意味着T<B>
也来自T<A>
。事实上,T<A>
和T<B>
被认为是两种截然不同的类型。
要看出原因并不容易,但让我们再举一个例子:
class Person
{
public string Name { get; set; }
}
class Student : Person
{
public char Grade { get; set; }
}
现在让我们假设这是允许的:
List<Student> students = new List<Student>();
List<Person> persons = students;
persons.Add(new Person()); // Oops!
基础列表仍然是学生列表,它不允许您添加Person
类型的对象!
好的,您的示例是不同的,如果您知道如何实现类型,它应该可以工作。但是C#只看到抽象语法结构,并且确实知道这些类型的真正意图。编译器无法说:“好的IEnumerable<T>
没有Add
方法,因此不会出现此问题”。因此,泛型类型不能自动成为共变或逆变。