【发布时间】:2009-08-23 21:49:25
【问题描述】:
下面的代码在 C# 中不合法有什么合理的原因吗?
class X: IA, IB
{
public X test() // Compliation Error, saying that X is not IB
{
return this;
}
}
interface IA
{
IB test();
}
interface IB { };
【问题讨论】:
下面的代码在 C# 中不合法有什么合理的原因吗?
class X: IA, IB
{
public X test() // Compliation Error, saying that X is not IB
{
return this;
}
}
interface IA
{
IB test();
}
interface IB { };
【问题讨论】:
更新:这个答案写于 2009 年。经过 20 年的时间,人们提出了 C# 的返回类型协方差,看起来它终于要实现了;我比较吃惊。公告见底部https://devblogs.microsoft.com/dotnet/welcome-to-c-9-0/;我相信接下来会详细介绍。
此功能称为“返回类型协方差”。 C# 不支持它,原因如下:
1) CLR 不支持它。为了让它在 C# 中工作,我们只需要吐出一大堆小助手方法,它们将返回类型强制转换为正确的东西。没有什么能阻止你自己这样做。
2) Anders 认为返回类型协方差不是一个好的语言特性。
3) \我们对语言有很多更高的优先级。我们只有有限的预算,所以我们尽量只在任何给定版本中做最好的功能。当然,这会很好,但如果你愿意,它很容易自己做。我们最好花时间添加可改善开发人员体验或为语言增加更多表现力的功能。
【讨论】:
您可以使用显式接口实现来避免该问题。
class X : IA, IB
{
public X test()
{
return this;
}
IB IA.test()
{
return this;
}
}
interface IA
{
IB test();
}
interface IB
{
}
【讨论】:
签名必须与接口指定的完全匹配。没有理由不能从方法中返回 X 的实例,但方法签名必须使用 IB。
出于合理的原因.. 从代码可读性的角度来看,它可能更可取。
您可以显式实现接口,并提供一个替代签名,该签名返回接口未定义的X。如果您知道您的 IA 实际上是 X,则可以使用它。
【讨论】:
因为 C# 在编译时不支持接口的 co 和 contravriance。这样,IA.Test() 方法的实现必须与其声明完全匹配。但是,您可以在运行时返回 X 的实例
【讨论】:
public X test();
您必须为任何非抽象类中的所有方法声明一个主体。
试试这个:
class X : IA, IB
{
public IB test()
{
return new X();
}
}
interface IA
{
IB test();
}
interface IB { };
【讨论】:
【讨论】: