Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么可以';除了在其声明中,不能给类主体中的属性赋值吗?_C# - Fatal编程技术网

C# 为什么可以';除了在其声明中,不能给类主体中的属性赋值吗?

C# 为什么可以';除了在其声明中,不能给类主体中的属性赋值吗?,c#,C#,我希望这个问题不要太傻-我找不到答案,部分原因是我不知道如何表达它,但我认为少量代码可以很好地解释它: class MyClass { int value = 10; } 这到底是干什么的?鉴于此 class MyClass { int value; value = 10; } 不起作用(可以理解-当我们不使用实际实例时,为类的成员赋值是没有意义的,并且这个成员不是静态的),因此我希望前者也不起作用-但我想它可能只是“创建实例时将这个成员初始化为10”的简短表

我希望这个问题不要太傻-我找不到答案,部分原因是我不知道如何表达它,但我认为少量代码可以很好地解释它:

class MyClass
{
    int value = 10;
}
这到底是干什么的?鉴于此

class MyClass    
{
    int value;
    value = 10;
}
不起作用(可以理解-当我们不使用实际实例时,为类的成员赋值是没有意义的,并且这个成员不是静态的),因此我希望前者也不起作用-但我想它可能只是“创建实例时将这个成员初始化为10”的简短表示法,是这样吗?

这样做:

class MyClass
{
  MyClass(int value)
 {
  this.value = value; 
 }
}
稍后创建新实例时:

MyClass classExample = new MyClass(3); // 3 is example value for int value.
// this would set the value to 3 for the "classExample"-instance of class "MyClass".
或者设置默认值:

    class MyClass
{
  MyClass()
 {
  value = 0; // default value would be 0 for all new instances of MyClass. 
 }
}

这称为字段初始值设定项。正如您所说,这只是“创建实例时将此成员初始化为10”的内联快捷方式

初始化发生在构造函数调用之前


字段初始化是由语言定义的,因此编译器知道该做什么。类主体中的语句(如赋值=10)未由语言指定,从而导致编译器错误。这就是第二种方法不起作用的原因。

我将尝试给你一个更“高级”的答案,同时保持简单的术语

语句(例如对字段/变量的赋值)需要是方法体的一部分

第一个示例之所以有效,是因为它是一个C#编译器技巧

在后台,它所做的是通过生成的构造函数方法设置值。为了说明这一点,我将您的类的C#代码反编译为IL,即它编译到的中间语言

(我知道代码看起来很奇怪,但它是.net生态系统的秘密语言)

您的第二个示例不起作用,因为它不是方法主体的一部分。C#不知道什么时候运行它

您可以将其更改为自己创建的构造函数:

class MyClass
{
    int value;

    public MyClass()
    {
        value = 10;
    }
}

这是行不通的,这是一个成员声明,然后是一些声明。在类定义的主体中不能有这样的语句。可以像在第一个示例中那样为类字段指定默认值。如果要将其分配到声明以外的其他位置,则必须在方法(或属性)中进行分配。通常,构造函数用于指定默认值。第一个赋值之所以有效,是因为它是字段声明的一部分。您的想法是错误的。正确的方法是
,后者是正确的。它不应该这样工作。前者是为了方便您摆脱不必要的构造函数而提供的功能。这是一条便捷的捷径。
所以一般来说,你会问-
为什么有一条便捷的捷径可以让我的生活更轻松?
我说得通吗?
class MyClass
{
    int value;

    public MyClass()
    {
        value = 10;
    }
}