C#编译器的泛型,继承和失败的方法解析
我今天碰到了编辑问题,这让我感到困惑.考虑这两个容器类.
public class BaseContainer<T> : IEnumerable<T> { public void DoStuff(T item) { throw new NotImplementedException(); } public IEnumerator<T> GetEnumerator() { } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { } } public class Container<T> : BaseContainer<T> { public void DoStuff(IEnumerable<T> collection) { } public void DoStuff <Tother>(IEnumerable<Tother> collection) where Tother: T { } } 前者定义了DoStuff(T项),后者用DoStuff< Tother>(IEnumerable< Tother>)重载它,专门用于解决缺少covariance/contravariance的C#(直到4听到). 这段代码 Container<string> c = new Container<string>(); c.DoStuff("Hello World"); 遇到一个相当奇怪的编译错误.注意缺少< char>从方法调用.
本质上,编译器试图将我对DoStuff(字符串)的调用阻塞到Container.DoStuff< char>(IEnumerable< char>)中,因为字符串实现了IEnumerable< char>,而不是使用BaseContainer.DoStuff(字符串). 我发现进行此编译的唯一方法是将DoStuff(T)添加到派生类 public class Container<T> : BaseContainer<T> { public new void DoStuff(T item) { base.DoStuff(item); } public void DoStuff(IEnumerable<T> collection) { } public void DoStuff <Tother>(IEnumerable<Tother> collection) where Tother: T { } } 为什么编译器试图将字符串堵塞为IEnumerable< char> 1)它知道它不能(假设存在编译错误)和2)它在基类中有一个编译好的方法?我是否误解了C#中的泛型或虚拟方法的东西?除了向Container添加新的DoStuff(T项)之外,还有其他修复方法吗? 解决方法
编辑
好的……我想我现在看到你的困惑了.您可能希望DoStuff(字符串)将参数保留为字符串,然后首先查找BaseClass方法列表以查找合适的签名,并且尝试将参数转换为其他类型时失败. 但它发生了反过来……相反,Container.DoStuff(字符串)去了,嗯“theres一个基类方法适合该法案,但我将转换为IEnumerable并对可用的内容进行心脏病发作在当前的班级而不是…… 嗯……我肯定Jon或Marc能够在这一点上用特定的C#Spec段落来报道这个特殊的角落案例 原版的 两种方法都期望IEnumerable Collection 你正在传递一个单独的字符串. 编译器正在接受该字符串并继续
编译器错误 那么修复是什么,它完全取决于你想要实现的目标…以下两个都是有效的,基本上,你的类型用法在你的化身中是不正确的. Container<char> c1 = new Container<char>(); c1.DoStuff("Hello World"); Container<string> c2 = new Container<string>(); c2.DoStuff(new List<string>() { "Hello","World" }); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |