为什么C#不允许我将void方法作为return语句的一部分?

我很好奇,如果有一个合法的原因,为什么C#不支持调用void方法作为返回语句的一部分,当调用方法的返回types也是void。

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#如何处理无效的语言限制吗?

因为这只是语言的定义方式 。

一个方法可以使用return语句来将控制权返回给调用者。 在返回void的方法中, return语句不能指定expression式。 在返回非void的方法中, return语句必须包含一个计算返回值的expression式。

这是一个任意的决定(大概是为了与ANSI C及其后代兼容),其他语言做不同的事情。

例如,在Python中,所有函数都会返回一个值。 如果你执行一个没有值的return语句,或者让控件到达函数的末尾,那么就像你写了return None

相比之下,Pascal将function的术语限制为具有返回值的子程序; 如果你不想返回任何东西,你可以使用一个procedure

void是信息的缺失; 返回它没有任何意义。 这不是一种types*,它不像其他一些语言那样是一种价值。 不,这不是一个限制。

*好,就像@Lucas指出的那样。 这是一个信息types; 它实际上并不代表通常意义上的types。 你不能有一个。

你的问题是关于voidtypes和unittypes (在F#等函数式语言中最常见的)之间的区别。

基本上, void不是一个真正的types。 虽然有System.Void为reflection目的,你不能使用void在大多数地方,你可以使用一个真正的types:你不能有一个voidtypes的variables,你不能用generics(即使是能写Func<void>有时候会非常有用)。

另一方面,F#中的unit是一个实数types:它有一个(单个)值(称为() ),可以写成相当于Func<void> (写unit -> unit ,其中第一个unit表示“no参数“,类似于在C中的参数列表中写入void ),并且可以具有unittypes的variables。 例如:

 let unitTest (f : unit -> unit) = let nothing : unit = f() () 

最后一行实际上表明,在F#中,你有时必须明确地返回unit

这归结于语言devise者的select。

从types的angular度来看,void没有可枚举的值,所以返回“void”types的值是没有意义的。 void是缺lesstypes或评估上下文。

你不能在C#或Java中实例化或返回“void”。

如果你能这样做,那么你也应该能够说:

  void i; i = (what would go here?) return i; 

以上没有任何意义,但相当于你的build议。

最后,提出可以用返回语句来传播无效返回上下文只是一个语法糖的问题,这个问题归结于语言devise者的select。

C#语言规范http://msdn.microsoft.com/en-us/library/aa691305(v=vs.71).aspx(7.1节)说

没有。 当expression式是一个返回types为void的方法的调用时,会发生这种情况。 被分类为“无”的expression式仅在语句expression式的情况下有效(见第8.6节)。

另一方面,C ++devise者实际上select只允许你提出的构造,但是它特别适用于模板中的语法一致性。 在C ++中,模板函数的返回types可以是模板参数。 (Stroustrop C ++编程语言,第148页)如果没有它,将会出现所有types都会编译的常见情况,而不是voidtypes的嵌套函数调用。因此,以下是有效的C ++:

 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(); 

所以语句expression式“return B();” 其中B是无效函数只是“B(); return”的快捷方式。 而实际上并没有产生价值 ,因为没有这样的东西作为空值。

根据语言规范,这是不允许的。 从ECMA-334(重点矿)的15.9.4开始:

具有expression式的return语句只能用于计算值的函数成员,即具有非void返回types的方法 ,属性或索引器的get访问器或用户定义的运算符。

我有一个合法的原因猜测。

当编译器看到一个expression式时,它会尝试将它与已知expression式列表中的内容进行匹配。 你可以说有两种以return开头的语句:

  1. return expr其中, expr是一个可分配给包含方法的声明返回types的expression式
  2. 没有任何其他的return

这些是完全不同的陈述,即使它们看起来相似。 但是在某些情况下, 可以编译到另一个(就像foreach编译到一些东西一样)。 所以,你可以添加一个规则,说, return expr编译为任何expr; return; expr; return; 编译为,只要expr被确定为没有返回types(即void )。

但是,那么C#编译器的实现者将不得不允许所有expression式没有返回types,通常只有语句被允许没有返回types。 如果他们这样做,那么他们将不得不手动禁止在任何需要实际types的地方使用任何types的expression式。 例如,在充当函数调用MyMethod(1, 2, SomethingVoid())参数的expression式中,编译器还需要检查这些expression式中的任何一个是否不返回types。 对于将来添加到C#中的每一种新的expression式,都必须添加相同的检查。

以上是可能的,但除了允许抽象语法树中的非语句expression式(在编译过程中生成)没有返回types之外,没有任何理由会发生这种情况,只是为了允许一个小的语法结构 – 而且有一种替代方法不再(按键式)input并可能更清晰地阅读。

最后,这听起来不值得。

你真正的问题标题似乎并没有被答案覆盖,虽然他们可能正在得到正确的东西。 你是问题标题

为什么C#不支持返回一个void返回types的方法

其实C#确实允许这个,只是不是你想要的格式。 使用void关键字作为其他人的答案意味着该方法不返回任何内容。 如果你想返回一个方法,那什么都不返回,那么你想要做这样的事情:

 public Action MethodExample() { return () => { Console.WriteLine("Hello World!"); }; } 

然后一个简单的电话会给你这个动作:

 var action = MethodExample(); action(); // prints Hello World 

虚空是空的。 C#语言中的void关键字指示方法不返回任何内容。 当一个void方法被调用时,它没有结果,也没有variables可以被分配。

看到这个解释

纠正我,如果我错了,但我认为它是因为:

 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 } }