gpt4 book ai didi

c# - 为什么 C# 编译器在从不同的基类派生时会报错 "types may unify"?

转载 作者:IT王子 更新时间:2023-10-29 03:41:04 26 4
gpt4 key购买 nike

我目前的非编译代码是这样的:

public abstract class A { }

public class B { }

public class C : A { }

public interface IFoo<T>
{
void Handle(T item);
}

public class MyFoo<TA> : IFoo<TA>, IFoo<B>
where TA : A
{
public void Handle(TA a) { }
public void Handle(B b) { }
}

C# 编译器拒绝编译它,引用以下规则/错误:

'MyProject.MyFoo<TA>' cannot implement both 'MyProject.IFoo<TA>' and 'MyProject.IFoo<MyProject.B>' because they may unify for some type parameter substitutions

我明白这个错误的意思;如果 TA 可以是任何东西,那么它在技术上也可以是 B,这会在两个不同的 Handle 实现中引入歧义。

但 TA 不能是任何东西。根据类型层次结构,TA 不能B - 至少,我认为它可以。 TA 必须派生自 A 派生自 B,显然 C# 中没有多类继承/.NET.

如果我删除通用参数并将 TA 替换为 C,甚至 A,它会编译。

那么为什么会出现这个错误呢?它是编译器中的错误或一般的非智能,还是我遗漏了其他东西?

是否有任何解决方法,或者我是否只需要为每个可能的 TA 派生类型重新实现 MyFoo 泛型类作为单独的非泛型类?

最佳答案

这是 C# 4 规范第 13.4.2 节的结果,其中指出:

If any possible constructed type created from C would, after type arguments are substituted into L, cause two interfaces in L to be identical, then the declaration of C is invalid. Constraint declarations are not considered when determining all possible constructed types.

注意那里的第二句话。

因此这不是编译器中的错误;编译器是正确的。有人可能会争辩说这是语言规范中的一个缺陷。

一般来说,几乎在所有必须推导出关于泛型类型的事实的情况下,约束都会被忽略。约束主要用于确定泛型类型参数的有效基类,仅此而已。

不幸的是,正如您所发现的,这有时会导致语言过于严格。


通常来说,实现“相同”接口(interface)两次是不好的代码味道,在某种程度上仅通过泛型类型参数来区分。奇怪的是,例如,class C : IEnumerable<Turtle>, IEnumerable<Giraffe> -- 什么是 C,它既是乌龟序列,又是长颈鹿序列,同时?你能描述一下你想在这里做的实际事情吗?可能有更好的模式来解决实际问题。


如果实际上您的界面与您描述的完全一样:

interface IFoo<T>
{
void Handle(T t);
}

然后接口(interface)的多重继承提出了另一个问题。您可能会合理地决定使此接口(interface)逆变:

interface IFoo<in T>
{
void Handle(T t);
}

现在假设你有

interface IABC {}
interface IDEF {}
interface IABCDEF : IABC, IDEF {}

class Danger : IFoo<IABC>, IFoo<IDEF>
{
void IFoo<IABC>.Handle(IABC x) {}
void IFoo<IDEF>.Handle(IDEF x) {}
}

现在事情变得非常疯狂......

IFoo<IABCDEF> crazy = new Danger();
crazy.Handle(null);

Handle 的哪个实现被调用???

有关此问题的更多想法,请参阅本文和评论:

http://blogs.msdn.com/b/ericlippert/archive/2007/11/09/covariance-and-contravariance-in-c-part-ten-dealing-with-ambiguity.aspx

关于c# - 为什么 C# 编译器在从不同的基类派生时会报错 "types may unify"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7664790/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com