为什么C#不允许我调用void方法作为return语句的一部分?
我很好奇,当调用方法的返回类型也是void时,为什么C#不支持将void方法作为return语句的一部分来调用,是否有正当的理由为什么C#不允许我调用void方法作为return语句的一部分?,c#,void,C#,Void,我很好奇,当调用方法的返回类型也是void时,为什么C#不支持将void方法作为return语句的一部分来调用,是否有正当的理由 public void MethodA() { return; } public void MethodB() { return MethodA(); } 所以我们通常会看到: public void MethodMeh() { if (expression) { MethodA(); r
public void MethodA()
{
return;
}
public void MethodB()
{
return MethodA();
}
所以我们通常会看到:
public void MethodMeh()
{
if (expression)
{
MethodA();
return;
}
// Do more stuff
}
。。。当我们可以使用此选项时:
public void MethodAwesome()
{
if (expression)
return MethodA();
// Do more stuff
}
这是由于C#如何处理void造成的语言限制吗?
void
是缺少信息;退回它没有任何意义。它不是一个类型*,也不是一个值,这与其他一些语言不同。不,这不是真正的限制
*就像@Lucas指出的那样。这是一种信息类型;它实际上并不代表通常意义上的类型。你不能有一个
空白为空。C语言中的void关键字表示
方法不返回任何内容。调用void方法时,它没有
结果,无法分配任何变量
根据语言规范,这是不允许的。根据ECMA-334(重点矿山)第15.9.4节: 带有表达式的return语句只能在计算值的函数成员中使用 是具有非无效返回类型的方法,是属性或索引器的get访问器,或用户定义的 接线员
这取决于语言设计师的选择 从类型的角度来看,void没有可枚举的值,所以返回“void”类型的值没有意义?void是指缺少类型或计算上下文 不能在C#或Java中实例化或返回“void” 如果你可以这样做,那么你也应该能够说:
void i;
i = (what would go here?)
return i;
上述内容没有任何意义,但与您的建议相同
最后,提出我们可以用return语句传播void return上下文只是一个语法糖分的问题,这可以归结为语言设计者的选择
C语言规范
(第7.1节)说
没什么。当表达式是对返回类型为void的方法的调用时,会发生这种情况。归类为nothing的表达式仅在语句表达式的上下文中有效(第8.6节)
另一方面,C++设计器实际上选择了只允许您提出的构造,但它特别是为了模板中的语法一致性。在C++中,模板函数的返回类型可以是模板参数。(Struoup C++ C++语言程序148)没有它,将有所有类型的通用情况,但不是空洞,例如类型T的嵌套函数调用。
void B() {
return;
}
void A() {
return B(); // legal C++ - doesn't yield a value
}
// But even in C++ the next line is illegal
int i = A();
因此,语句表达式“return B();”,其中B是一个void函数,它只是“B();return;”的一个快捷方式,实际上并不产生值,因为没有void值 因为这只是一种方式 方法可以使用
return
语句将控件返回给调用方。
在返回void
的方法中,return
语句不能指定
表达式。在返回非void
的方法中,return
语句必须
包括计算返回值的表达式
这是一个任意的决定(可能是为了与ANSIC及其后代兼容),其他语言的做法也不同
例如,在Python中,所有函数都返回一个值。如果执行一个不带值的return
语句,或者让控件到达函数的末尾,那么这就像编写了returnnone
一样
相反,Pascal将
函数的术语限制为具有返回值的子程序;如果您不想返回任何内容,可以使用过程来代替。您的问题主要是和之间的区别(最常见于函数式语言,如F#)
基本上,void
不是真正的类型。虽然存在用于反射的变量,但在大多数可以使用实类型的地方,不能使用void
:不能有void
类型的变量,也不能在泛型中使用它(即使能够编写Func
有时会非常有用)
另一方面,F#中的unit
是一个实数类型:它有一个(单个)值(称为()
),您可以编写Func
(写入unit->unit
,其中第一个unit
表示“无参数”,类似于在C中的参数列表中写入void
)您可以有unit
类型的变量。例如:
let unitTest (f : unit -> unit) =
let nothing : unit = f()
()
最后一行实际上表明,在F#中,有时必须显式返回unit
我猜这是一个合理的原因
当编译器看到一个表达式时,它会尝试将其与已知表达式列表中的某个内容进行匹配。您可以说有两种以return
开头的语句:
returnexpr
其中expr
是可分配给包含方法的声明返回类型的表达式
返回
不带任何其他内容
这些说法完全不同,即使它们看起来很相似。但在某些情况下,一个可以编译成另一个(就像foreach
编译成while
plus东西)。因此,您可以添加一条规则,说明returnexpr
编译到任何expr;返回只要expr
被确定为无返回类型(即void
),code>就会编译为
但是,C#编译器的实现者必须允许所有表达式都没有返回类型,而通常只允许语句没有返回类型。如果他们这样做了,那么他们将不得不手动禁止no的表达式
public Action MethodExample()
{
return () => { Console.WriteLine("Hello World!"); };
}
var action = MethodExample();
action(); // prints Hello World
public void MethodA()
{
return;
}
public void MethodB()
{
return MethodA();
}
public void MethodA()
{
}
public void MethodB()
{
MethodA();
}
public void MethodMeh()
{
if (expression)
{
MethodA();
}else{
// do more stuff
}
}