声明和初始化变量

本文关键字:变量 初始化 声明 | 更新日期: 2023-09-27 17:55:59

我想知道为什么我们不能这样做:

public partial class Form1 : Form
{
    string b;
    b = "something";
    public Form1()
    {
        InitializeComponent();
    }

但是我能够做到这一点:

public partial class Form1 : Form
{
    string b = "something";

public partial class Form1 : Form
{
    string b;
    private void Form1_Load(object sender, EventArgs e)
    {
        b = "something";
    }

我一直在寻找答案,为什么我们不能使用第一种方法。但是,我一直无法找到答案。

声明和初始化变量

在 C# 中,类可以包含以下成员的声明...

Constructors Destructors Constants Fields Methods Properties Indexers Operators Events Delegates Classes Interfaces Structs

为变量赋值被视为statement。同样,语句也分为各种类型。现在,您的问题出现了Declaration statementsExpression statements之间的混淆。

声明语句

:声明语句用于引入常量字段需要赋值的fields,而变量是可选的。从技术上讲,Declaration statements使用Expression statements作为其中的一部分。

表达式语句

:另一方面,表达式语句的职责是为变量赋值。但是创建一个变量不是它的责任。

因此,为了声明类的字段和常量,Declaration Statements参与并在技术上Expression Statements作为其中的一部分。但独立Expression Statements以及其他语句只能是方法、属性或事件声明的一部分。

您可以从这里获得有关课程的更多信息以及关于此处的声明

我一直在寻找答案,为什么我们不能使用第一种方法。

嗯,主要是因为 C# 团队认为这样做不是一个好主意,或者因为他们一开始就没有这个想法。

但是,让我们先花点时间:

您当然可以将其作为功能请求。在这一点上,他们将平衡利弊。让我们这样做,并考虑以下代码段:

public class Foo
{
    int x = 12;
    int y;
    y = 12 + MyMethod();
    public Foo()
    {
        y = MyMethod();
    }
    public int MyMethod() 
    { 
       //***
       return x + 1;
    }
}

现在,构造函数Foo将在 Foo 初始化时调用。那么,初始化后y会有什么价值呢?我们将调用MyMethod多少次?如果我们添加第二个构造函数会发生什么?

我会说这很令人困惑,所有这些混乱并不是真正必要的,因为有很好的结构("构造函数"和字段赋值速记)已经允许你用大约相同数量的代码做必要的事情。

所以有缺点,没有优点。

总而言之,我

不希望在我的代码中使用这种结构,这就是为什么我怀疑这是否会得到支持。

此语句:

string b;

是一个初始化语句。 类主体中只允许初始化和声明/定义。

此声明:

b = "something";

是一种赋值语句,一种表达式。 它实际上"返回"了一些东西,b。

此声明:

string b = "something";

这也是一个初始化语句。 你可以写这个,但不能写赋值语句,是因为 c# 的形式语言不允许你这样做。我还没有看到正式的语言定义,但我想它看起来像这样

InitializationStatement => TypeExpression Symbol  {AssignmentExpressionStatement | ';'}
AssignmentExpressionStatement => '=' EvaluatableExpression ';'

大括号表示里面的内容是可选的,管道表示 or 。这就是使语言成为编译器可以理解的语言的原因。 这些规则越灵活,为它做编译器就越困难,为它做开发软件越困难,代码就越混乱。


TLDR:你不能把它们放进去,就像你不能把2+2放在类声明中一样。

在 C# 语言中,可执行表达式应驻留在方法中。类本身不可执行。它们为对象的行为方式提供了蓝图。类只能具有方法和属性。在 C# 属性中,类中也允许事件和委托。但在内部属性、事件和委托也是方法和变量。

public partial class Form1 : Form
{
string b;
b = "something";
public Form1()
{
    InitializeComponent();
}
}

在这里,字符串 b; 是一个变量声明。 b="something" 是一个可执行表达式。所以你不能直接在类中有 b="something"。但是字符串 b = "某物";是一种称为初始化的特殊语法。这是在 C# 语言中定义的。否则,您应该将 b="something" 移动到包括构造函数在内的某个方法。内部初始化代码在创建新对象时运行,在调用构造函数之前,我们可以将其视为构造函数的一部分。