【问题标题】:Declaring and Initialising variables声明和初始化变量
【发布时间】:2015-06-12 20:10:26
【问题描述】:

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

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

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

【问题讨论】:

  • b 是与Form1 类关联的字段,而不是通常意义上的变量。变量只能在方法、属性或构造函数中重新分配。我敢肯定有更多涉及 C# 语言规范的技术解释。
  • 一步声明和初始化时,值作为声明的一部分赋值。正如@ryanyuyu 所说,b= "something"; 是一个完整的语句,它在执行语句的正常结构之外。
  • 'b = "某事";'是一个语句,并且语句不能存在于方法、属性或事件声明之外。你不能在你有它的地方拥有它,而且你不能在那里拥有if 声明。

标签: c# .net variables visual-studio-2012 variable-declaration


【解决方案1】:

在 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 以及其他语句只能是方法、属性或事件声明的一部分。

你可以从here获得更多关于课程的信息 以及来自here的声明

【讨论】:

    【解决方案2】:

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

    嗯,基本上是因为 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 多少​​次?如果我们添加第二个构造函数会发生什么?

    我会说这很令人困惑,而且所有这些混乱并不是真正必要的,因为有很好的构造(“构造函数”和字段分配简写)已经允许您使用大约相同数量的代码来完成必要的事情.

    所以有缺点,没有优点。

    总而言之,我不希望在我的代码中使用这些类型的结构,这就是为什么我怀疑它是否会得到支持。

    【讨论】:

      【解决方案3】:

      此声明:

      string b;
      

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

      此声明:

      b = "something";
      

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

      此声明:

      string b = "something";
      

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

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

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


      TLDR:您不能将它们放入类声明中,原因与您不能将 2+2 放入类声明中的原因相同。

      【讨论】:

        【解决方案4】:

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

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-11-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多