将 IEnumerable 隐式转换为泛型类型
Implicit casting IEnumerable to generic type
我在使用隐式转换和 IEnumerable 时遇到了一个有趣的案例 - 请查看附加代码的最后一行 - 它无法编译。
public class Outer<T>
{
private T field;
public Outer(T it)
{
field = it;
}
public static implicit operator Outer<T> (T source)
{
return new Outer<T>(source);
}
}
void Main()
{
Outer<string> intsample = "aa";
Outer<IList<object>> listsample = new List<object>();
//The line below fails with:
//CS0266 Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<object>'
//to 'UserQuery.Outer<System.Collections.Generic.IEnumerable<object>>'.
//An explicit conversion exists (are you missing a cast?)
Outer<IEnumerable<object>> enumerablesample = Enumerable.Empty<object>();
}
我有一种非常强烈的直觉,很高兴 IEnumerable
是协变的,但是有人可以更正式地解释一下吗?
The docs 状态:
A class or struct is permitted to declare a conversion from a source
type S to a target type T provided all of the following are true:
- S and T are different types.
- Either S or T is the class or struct type in which the operator declaration takes place.
- Neither S nor T is object or an interface-type. T is not a base class of S, and S is not a base class of T.
简单的解决方法是更改:
Enumerable.Empty<object>();
至:
new List<object>();
因为 List
不是接口(感谢@PatrickHofman!)。
我在使用隐式转换和 IEnumerable 时遇到了一个有趣的案例 - 请查看附加代码的最后一行 - 它无法编译。
public class Outer<T>
{
private T field;
public Outer(T it)
{
field = it;
}
public static implicit operator Outer<T> (T source)
{
return new Outer<T>(source);
}
}
void Main()
{
Outer<string> intsample = "aa";
Outer<IList<object>> listsample = new List<object>();
//The line below fails with:
//CS0266 Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<object>'
//to 'UserQuery.Outer<System.Collections.Generic.IEnumerable<object>>'.
//An explicit conversion exists (are you missing a cast?)
Outer<IEnumerable<object>> enumerablesample = Enumerable.Empty<object>();
}
我有一种非常强烈的直觉,很高兴 IEnumerable
是协变的,但是有人可以更正式地解释一下吗?
The docs 状态:
A class or struct is permitted to declare a conversion from a source type S to a target type T provided all of the following are true:
- S and T are different types.
- Either S or T is the class or struct type in which the operator declaration takes place.
- Neither S nor T is object or an interface-type. T is not a base class of S, and S is not a base class of T.
简单的解决方法是更改:
Enumerable.Empty<object>();
至:
new List<object>();
因为 List
不是接口(感谢@PatrickHofman!)。