为什么 list.Add(new B())
编译和list.Add(new Wrapper<B>())
不编译?我认为要么两者都编译,要么都不编译,因为我认为编译器能够找出 B
的隐式转换。返回 Wrapper<B>
这是从new Wrapper<B>()
生产的同一类型.我在 VS 2012 中使用 C# 4。
class Wrapper<T> where T : new()
{
public static implicit operator Wrapper<T>(T obj)
{
return new Wrapper<T>();
}
public static implicit operator T(Wrapper<T> obj)
{
return new T();
}
}
class A { }
class B : A { }
class MyClass
{
public static void Main(string[] args)
{
List<Wrapper<A>> list = new List<Wrapper<A>>();
//This line compiles and runs successfully
list.Add(new B());
//This line doesn't compile
list.Add(new Wrapper<B>());
}
}
最佳答案
从您的问题看来,您认为添加 B
的实例到 Wrapper<A>
的列表工作是因为 B
隐式转换为 Wrapper<B>
,以某种方式添加到列表中。然而,事实并非如此。事实上,编译器无法从 Wrapper<B>
进行转换。至 Wrapper<A>
一步到位。
添加 B
实例的原因到 Wrapper<A>
的列表有效是因为编译器看到 B
延伸A
并且有一个来自 A
的用户定义的隐式转换至 Wrapper<A>
.
您可能认为您还可以添加 Wrapper<B>
到 Wrapper<A>
的列表因为有一个来自 Wrapper<B>
的用户定义的隐式转换至 B
和 B
延伸A
并且有一个来自 A
的用户定义的隐式转换至 Wrapper<A>
.但是,根据规范(第 6.4.4 节详述 here),您不能以这种方式将用户定义的隐式转换链接在一起。事实上,最小示例甚至不需要处理泛型。考虑这个简单的问题示例:
class A
{
public static implicit operator B(A a) { return default(B); }
}
class B
{
public static implicit operator C(B a) { return default(C); }
}
class C
{
public static void Method(C c) { }
}
public static void Main()
{
C.Method(new A());
}
当然,如果你显式地进行转换,那么它就可以工作了:
public static void Main()
{
C.Method((B)new A());
}
关于c# - 将通用对象添加到列表时出现编译错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16817548/