加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

C#编译器的泛型,继承和失败的方法解析

发布时间:2020-12-15 04:22:14 所属栏目:百科 来源:网络整理
导读:我今天碰到了编辑问题,这让我感到困惑.考虑这两个容器类. public class BaseContainerT : IEnumerableT{ public void DoStuff(T item) { throw new NotImplementedException(); } public IEnumeratorT GetEnumerator() { } System.Collections.IEnumerator S
我今天碰到了编辑问题,这让我感到困惑.考虑这两个容器类.
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>从方法调用.

The type ‘char’ cannot be used as type parameter ‘Tother’ in the generic type or method ‘Container.DoStuff(System.Collections.Generic.IEnumerable)’. There is no boxing conversion from ‘char’ to ‘string’.

本质上,编译器试图将我对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

你正在传递一个单独的字符串.

编译器正在接受该字符串并继续

Ok,I have a string,Both methods
expect an IEnumerable<T>,So I’ll
turn this string into an
IEnumerable<char>… Done

Right,Check the first method…
hmmm… this class is a
Container<string> but I have an
IEnumerable<char> so that’s not right.

Check the second method,hmmm…. I
have an IEnumerable<char> but char
doesn’t implement string so that’s
not right either.

编译器错误

那么修复是什么,它完全取决于你想要实现的目标…以下两个都是有效的,基本上,你的类型用法在你的化身中是不正确的.

Container<char> c1 = new Container<char>();
        c1.DoStuff("Hello World");

        Container<string> c2 = new Container<string>();
        c2.DoStuff(new List<string>() { "Hello","World" });

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读