为什么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

我很好奇,当调用方法的返回类型也是void时,为什么C#不支持将void方法作为return语句的一部分来调用,是否有正当的理由

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