本文介绍了多个IEnumerable实现悖论的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


  1. 我有一个通用类A< T >,它实现了IEnumerable< T [] >。

  2. 我希望有一个便利包装器B,它继承自A< char >并实现IEnumerable< string >。

  1. I have a generic class A<T>, that implements IEnumerable<T[]>.
  2. I want to have a convenience wrapper B that inherits from A<char> and implements IEnumerable<string>.

public class A<T> : IEnumerable<T[]>
{
    public IEnumerator<T[]> GetEnumerator()
    {
        return Enumerate().GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    protected IEnumerable<T[]> Enumerate()
    {
        throw new System.NotImplementedException();
    }
}

public class B : A<char>, IEnumerable<string>
{
    public IEnumerator<string> GetEnumerator()
    {
        return Enumerate().Select(s => new string(s)).GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}


现在,这完全正常,foreach变量类型被推断为字符串:

Now, this works perfectly fine, foreach variable type is inferred to be string:

B b = new B();
foreach (var s in b)
{
    string[] split = s.Split(' ');
}

但这不会编译,说无法从中推断类型参数用法,尝试明确指定类型参数:

But this won't compile, saying "The type arguments cannot be inferred from usage, try specifying the type arguments explicitly":

string[] strings = b.ToArray();

然而,这有效:

string[] strings = b.ToArray<string>();

任何人都可以解释这种编译器行为吗?

Can anyone explain this compiler behavior?

显然,B实现IEnumerable< char [] >和IEnumerable< string >,可能它可以'弄清楚我想要调用哪一个,但为什么它在foreach样本中工作正常?

Obviously, B implements both IEnumerable<char[]> and IEnumerable<string> and probably it can't figure out which of them I want to call, but why it works fine in "foreach" sample?

请不要建议我通过构图解决我的问题 - 这是我的最后一招。

Please, don't suggest me to solve my problem by composition - this is the last resort for me.

推荐答案

区别如下:

foreach 实际上查找名为 GetEnumerator 的公共方法。它并不真正关心 IEnumerable< T> 。您的类 B 只有一个名为 GetEnumerator 的公共方法:在 B中定义的方法 隐藏 A 中定义的那个。

foreach actually looks for a public method called GetEnumerator. It doesn't really care for IEnumerable<T>. Your class B only has one public method named GetEnumerator: The one defined in B which hides the one defined in A.

<$另一方面,c $ c> ToArray 是 IEnumerable< T> 的扩展方法。由于你的班级是 IEnumerable< string> IEnumerable< char []> 两者之间的呼叫不明确泛型参数 string char []

ToArray on the other hand is an extension method on IEnumerable<T>. As your class is both IEnumerable<string> and IEnumerable<char[]> the call is ambiguous between the two generic arguments string and char[].

这篇关于多个IEnumerable实现悖论的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-28 16:37