更改结构中的各种值(它们的不可变程度如何?)

发布于 2024-12-20 09:41:07 字数 959 浏览 1 评论 0原文

我一直在广泛阅读有关结构的内容,并且我对在何处使用它们有很好的了解。但困扰我的一件事是,无论我读了多少,我都不理解结构的不变性。

我知道,就像字符串一样,如果您更改它们,您实际上会在内存中创建一个全新的对象,但这是否也适用于结构内的值。例如:例如

public struct SomeValues
{
    public int AnInt;
    public float AFloat;
    public string AString;
}
public SomeValues[] ArrayOfValues;
private void SomeFunctionThatRunsContinuously()
{
    /*so for every value I change, do I essentially create a whole new instance
      of SomeValues?*/

    for (int i = 0; i < ArrayOfValues.Length; i++)
    {
        //Is this another struct?
        ArrayOfValues[i].AnInt++;

        //And then another again?
        ArrayOfValues[i].AFloat += 0.33f;

        /*I realise adding letters to a string is a horrible idea 
                       -- but is it WORSE to do it in a struct?*/

        ArrayOfValues[i].AString += "s";
    }
}

,如果我有一个结构体,它保存 3D/2D 空间内每个人的坐标(给出坐标作为何时使用结构体的示例),并且人的位置发生变化,在两个/三个 int 结构中更新,可能是从一个数组,这是创建新的结构,因为它们是不可变的?

I've been reading up extensively on structs, and I have a decent understanding of where you would use them. One thing though bothers me is, no matter how much i read about it, I don't understand the immutability of structs.

I understand that, like strings, if you change them you essentially create an entirely new object in memory, but does this also hold for the values inside a struct. For instance:

public struct SomeValues
{
    public int AnInt;
    public float AFloat;
    public string AString;
}
public SomeValues[] ArrayOfValues;
private void SomeFunctionThatRunsContinuously()
{
    /*so for every value I change, do I essentially create a whole new instance
      of SomeValues?*/

    for (int i = 0; i < ArrayOfValues.Length; i++)
    {
        //Is this another struct?
        ArrayOfValues[i].AnInt++;

        //And then another again?
        ArrayOfValues[i].AFloat += 0.33f;

        /*I realise adding letters to a string is a horrible idea 
                       -- but is it WORSE to do it in a struct?*/

        ArrayOfValues[i].AString += "s";
    }
}

So for instance, if I had a struct which for instance was holding the coordinates of every person inside a 3D/2D space (coordinates were given as an example of when to use structs), and the positions of the people change and are updated inside a two/three int struct, from maybe an array, is that creating new structs because they're immutable?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

风铃鹿 2024-12-27 09:41:07

默认情况下,结构体不是是不可变的,设计该结构体使其表现是不可变的,这是一个非常好的主意。

因此对于不可变的结构/类

  • 不要使用公共字段,而是使用属性而不使用公共设置器。私有设置器很好,设置支持字段(从构造函数)也很好。
  • 只允许通过构造函数设置值。
  • 似乎修改结构的方法不应该修改它,它们应该返回一个新实例(想想 DateTime.AddYears)。

A struct is not immutable by default, it is just a very good idea to design the struct so that it acts immutable.

So for immutable structs/classes:

  • don't use public fields, use properties instead without a public setter. A private setter is fine, setting the backing-field (from the constructor) is also fine.
  • only allow values to be set through the constructor.
  • methods that appear to modify your struct should not modify it, they should return a new instance instead (think DateTime.AddYears).
柠檬 2024-12-27 09:41:07

结构不是不可变的,除非将其中的字段设置为只读。

public struct SomeValues 
{ 
    public readonly int AnInt; 
    public readonly float AFloat; 
    public readonly string AString; 
} 

Structs are not immutable unless you make the fields in them Read Only.

public struct SomeValues 
{ 
    public readonly int AnInt; 
    public readonly float AFloat; 
    public readonly string AString; 
} 
还在原地等你 2024-12-27 09:41:07

结构不是一成不变的。
内存中的新对象不是在您更改它时创建的,而是在您将其分配给不同的变量或作为参数传递给某个方法时创建的。

Struct are NOT immutable.
New object in memory is created not when you change it, but when you assign it to different variable or pass as argument to some method.

零度℉ 2024-12-27 09:41:07

结构不是一成不变的。虽然有些人似乎认为应该这样做,但大多数原因似乎分为三类:

  1. 允许结构体方法修改“this”,而类方法则不允许;因为禁止在只读上下文中的结构上使用任何和所有方法会很烦人 - 即使那些实际上不修改“this”的方法 - 编译器通过临时处理只读结构上的方法调用结构体的副本并在这些副本上运行方法;当这些方法返回时,这些方法可能所做的任何更改都会消失。
  2. 有些人没有意识到结构和类的行为不同。
  3. 某些语言功能期望进行代码转换,这对于可变结构可能不如对于不可变结构或类(可变或不可变)有效。

当值类型语义有意义时,请使用结构,尤其是当所讨论的实体是可变的时。考虑一下:

struct fancyRect {public int left,top,width,height; ....other stuff.... };

... then within some code ...
  myList = List<fancyRect>; // Assume this list has been initialized somehow
  fancyRect tempRect = myList[0];
  tempRect.left += 5;
  myList[0] = tempRect;

仅使用提供的信息就可以完全确定上述代码对 myList 内容的影响。如果属性可以通过引用公开,允许 myList[0].left += 5,那么会更清晰,但结构的代码仍然清晰易读。假设 tempRect 是一个类。上面的代码会产生什么效果呢?它还能有其他作用吗?如何对其进行编码才能使其具有与结构相同的语义?

Structs are not immutable. While some people seem to think they should be, most of the reasons seem to fall into three categories:

  1. Struct methods are allowed to modify "this", whereas class methods are not; since it would be annoying to forbid the use of any and all methods on structs in read-only context--even those which don't in fact modify "this"--compilers instead handle method calls on read-only structs by making temporary copies of the structs and running the methods on those copies; any changes those methods might make disappear when the methods return.
  2. Some people don't realize that structs and classes behave differently.
  3. Some language features expect to make code transformations which may not work as well with mutable structs as they do with immutable structs or classes (mutable or immutable).

When value-type semantics make sense, use structs, especially when the entities in question are mutable. Consider:

struct fancyRect {public int left,top,width,height; ....other stuff.... };

... then within some code ...
  myList = List<fancyRect>; // Assume this list has been initialized somehow
  fancyRect tempRect = myList[0];
  tempRect.left += 5;
  myList[0] = tempRect;

The effects of the above code on the contents of myList can be fully ascertained with only the information supplied. It would be cleaner if properties could be exposed by reference, allowing myList[0].left += 5, but the code for structs is still clear and readable. Suppose tempRect were instead a class. What effect would the above code have? Could it have other effects? How would one have to code it to have the same semantics as with structs?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文