为什么struct可以改变自己的领域?

Laz*_*zlo 5 c# struct

考虑Foo结构如下:

struct Foo
{
  public float X;
  public float Y;

  public Foo(float x, float y)
  {
    this.X = x;
    this.Y = y;
  }

  public void Change(float x)
  {
    this.X = x;
  }
}
Run Code Online (Sandbox Code Playgroud)

我理解修改构造函数中的字段,这对我和我理解结构作为值,类似数字的不可变类型是完全合乎逻辑的.

然而,因为可以T"做:

Foo bar = new Foo(1, 2);
bar.X = 5;
Run Code Online (Sandbox Code Playgroud)

为什么可以使用:

Foo bar = new Foo(1, 2);
bar.Change(5);
Run Code Online (Sandbox Code Playgroud)

编辑:如果结构是可变的,那么为什么它们不能在列表中修改或从属性返回?

无法修改表达式,因为它不是变量

Eri*_*ert 11

既然一个人做不到

Foo bar = new Foo(1, 2); 
bar.X = 5; 
Run Code Online (Sandbox Code Playgroud)

为什么可以使用:

Foo bar = new Foo(1, 2); 
bar.Change(5); 
Run Code Online (Sandbox Code Playgroud)

您的原始问题实际上无法回答,因为它是基于一个完全错误的假设.这两个代码示例都是完全合法的,因此关于为什么一个是非法的问题是荒谬的.让我们继续你的后续问题:

如果结构是可变的,那么为什么在列表中或从属性返回时它们不能被修改?

因为变量是可变的,值是不可变的.

这就是为什么他们被称为"变量",毕竟,因为他们可以改变.

当你说"bar.X = 5"时,"bar"是一个局部变量.变量可以更改.

当你说"bar.Change(5)"时,"bar"是一个局部变量.变量可以更改.

当你说"myArray [123] .X = 5"时,"myArray [123]"是一个数组元素,数组元素是一个变量.变量可以更改.

当你说"myDictionary [123] .X = 5"时,"myDictionary [123]" 不是变量.该从字典返回,而不是对存储位置的引用.由于这是一个值,而不是一个变量,因此没有任何东西可以改变,所以编译器不允许它改变.

一个微妙的问题是,当您尝试更改字段时,接收方必须是变量.如果它不是变量,那就毫无意义; 你显然是在试图改变一个变量而且没有什么可以变异的.当你调用一个方法时,接收者必须是一个变量但是如果你有一个值呢?该方法可能不会尝试改变任何东西,因此应该允许成功.如果方法的接收者在结构上调用不是变量,编译器实际上做了什么,然后它创建一个新的临时局部变量并使用该变量调用该方法.所以如果你说:"myDictionary [123] .Change(5);" 这跟说的一样

var temp = myDictionary[123];
temp.Change(5);
Run Code Online (Sandbox Code Playgroud)

这里"temp"是一个变量,允许变异方法改变临时副本.

那现在清楚了吗?这里的关键点是变量可以改变.


Ala*_*tts 8

你做了一个关键的错误假设.

.NET结构是可变的.你绝对可以表演bar.X = 5;.

您应该将结构设计为不可变的,但是根据您提供的代码,它们是可变的.

看一下这个问题,了解可变结构可能导致麻烦的地方. 结构的不变性

  • 我认为你的意思是"你应该设计结构是不可变的" (3认同)