【问题标题】:Can not cast my Matrix type to IEnumerable<IEnumerable<float>> [duplicate]无法将我的 Matrix 类型转换为 IEnumerable<IEnumerable<float>> [重复]
【发布时间】:2014-04-21 18:01:35
【问题描述】:

我有一个具有此签名的 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&lt;IEnumerable&lt;float&gt;&gt;。

但我不明白为什么不呢?

【问题讨论】:

标签: c# ienumerable


【解决方案1】:

Matrix 实现 IEnumerable&lt;Vector&gt; 但不是 IEnumerable&lt;IEnumerable&lt;float&gt;&gt;。要么让它实现IEnumerable&lt;IEnumerable&lt;float&gt;&gt;,要么将其转换为正确的类型:

IEnumerable<IEnumerable<float>> floatEnumerationEnumeration =
    matrix.Cast<IEnumerable<float>>();

请注意,如果B 派生自A,那么这并不意味着T&lt;B&gt; 也派生自T&lt;A&gt;。事实上T&lt;A&gt; 和T&lt;B&gt; 被认为是两种截然不同的不相关类型。

原因并不容易,但我们再举一个例子:

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&lt;T&gt; 没有 Add 方法,因此不会出现这个问题”。因此泛型类型不能自动协变或逆变。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多