在这篇文章中,编写的是在C# 8.0中包含新的不变返回类型特性,因为社区在很长一段时间内都在要求这个特性。
有谁能用实例来解释为什么和什么时候需要这个特性吗?
发布于 2018-04-05 09:31:41
首先,值得注意的是,这篇文章很可能是错误的。目前有一长串正式指定用于C# 8.0的特性,但协变量返回类型不是其中之一。这个特性计划在X.0 (它需要出现在一个主要版本中),所以它可能出现在8.0 (但这是难以置信的不可能),更有可能将在9.0或10.0等。
至于功能的用途是什么,读一读三年前的罗斯林原版。它可以在派生类型的方法中缩小返回类型,例如工厂接口的实现可以指定它返回一个具体类型,而不是一个接口。
例如,使用泛型,我们可以执行如下操作:
public interface IFactory<T>
{
T Create();
}
public class Foo{}
public class FooFactory : IFactory<Foo>
{
public Foo Create() => null;
}但是,如果IFactory使用更多的接口来进行抽象,而不是泛型,那么类似的代码目前是不可能的:
public interface IFoo {}
public interface IFactory
{
IFoo Create();
}
public class Foo : IFoo {}
public class FooFactory : IFactory
{
public Foo Create() => null; // Compiler complains at Foo; wants IFoo
}使用协变返回类型,这种代码将成为合法的。
发布于 2018-04-05 09:55:31
协变返回类型意味着方法覆盖可以指定比基本方法更特定的返回类型。例如:
class WebRequest {
virtual WebRequest Create() { ... }
}
class HttpWebRequest : WebRequest {
override HttpWebRequest Create() { ... }
}目前(没有协变量返回类型) overriden方法必须指定完全相同的返回类型WebRequest,您必须手动将返回值转换为HttpWebRequest,这很难看。
发布于 2018-04-05 12:13:36
(事先道歉,C#有点生疏)
正如在其他答案中提到的,不变返回类型的主要特性是,您可以使用返回更特定返回类型的函数覆盖虚拟函数。
例如:
public class Foo
{
virtual public Foo getCopy(); { //Create a copy of this Foo and return it }
}到目前为止,getCopy()方法返回在其上调用的Foo的副本。让我们添加一个从Foo继承的类。
public class Bar : Foo
{
override public Foo getCopy(); { //Create a copy of this Bar and return it as a Foo }
}注意,如果没有协变量返回类型,我们需要声明返回一个Foo (正式)而不是Bar (尽管我们实际上返回了一个Bar)。在编写以下代码之前,这可能不会那么糟糕。
//Copying things
Foo myFoo;
Foo myOtherFoo = myFoo.getCopy();
Bar myBar;
Bar myOtherBar = myBar.getCopy(); //Compiler error - getCopy() returns a Foo尽管您知道myBar是一个Bar,并且您(实际上)从myBars的getCopy()中获得了一个Bar,但是您需要转换返回值才能编译它。更糟的是,它是细菌的潜在来源.
public class Baz : Foo
{
override public Foo getCopy(); { //Create a copy of this Baz and return it as a Foo }
}
//Copying more things
Foo myFoo;
Foo myOtherFoo = myFoo.getCopy();
Bar myBar;
Bar myOtherBar = myBar.getCopy() as Bar;
Baz myBaz;
Baz myOtherBaz = myBar.getCopy() as Baz; //Whoops注意到错误了吗?如果没有协变量返回值,您可能只会在运行时(当程序崩溃时)注意到,编译器可以在编译时告诉您:不,这不能工作。
总之:协变量返回值允许您编写更短、更精确和更安全的代码。
https://softwareengineering.stackexchange.com/questions/368872
复制相似问题