Change the value of a property of a struct in C# [duplicate]

你说的曾经没有我的故事 提交于 2019-12-11 05:29:10

问题


I was reading a book and found out that structs are actually immutable objects. But they have getters and setters. I was wondering if a property of structs can be changed after it has been created.

public struct Test 
{
    public string str {get; set; }
    public int int1 {get; set; }
}

Can the values of 'str' and 'int1' be changed once they have been assigned a value?


回答1:


Structs can be either mutable or immutable, but they should be immutable according to many people.

Your example is a mutable struct.

Example of use:

var t = new Test();
// t.str is null, and t.int1 is 0

t.str = "changed!"; // OK

var t2 = t;
t2.int1 = 42;
// t.int1 is still 0

var li = new List<Test> { t, t2, };
t.int1 = 666;  // OK, but copy in li is unaffected

li[0].int1 = 911;  // compile-time error, not a variable

var t3 = t2;
bool checkA = (t3 == t2);  // compile-time error, you did not overload operator ==
bool checkB = t3.Equals(t2);  // OK, true, ValueType class overrides Equals for you
bool checkC = t2.Equals(t);  // OK, false
bool checkD = object.ReferenceEquals(t, t);  // false, two distinct boxes
                                             // same as (object)t==(object)t

By request, here is one way to make that struct immutable:

public struct Test 
{
    public string str { get; private set; }
    public int int1 { get; private set; }

    public Test(string str, int int1) : this()
    {
        this.str = str;
        this.int1 = int1;
    }
}
// if you introduce methods (other than constructors) that use the private setters,
// the struct will no longer be immutable

and here is another one:

public struct Test 
{
    readonly string m_str;
    readonly int m_int1;

    public string str { get { return m_str; } }
    public int int1 { get { return m_int1; } }

    public Test(string str, int int1)
    {
        m_str = str;
        m_int1 = int1;
    }
}



回答2:


Can the values of 'str' and 'int1' be changed once they have been assigned a value?

Yes, struct's properties can be changed. structs are not immutable per se.

But it is considered a good design to make them unchangeable.

From Struct Design:

X DO NOT define mutable value types.

Mutable value types have several problems. For example, when a property getter returns a value type, the caller receives a copy. Because the copy is created implicitly, developers might not be aware that they are mutating the copy, and not the original value. Also, some languages (dynamic languages, in particular) have problems using mutable value types because even local variables, when dereferenced, cause a copy to be made.




回答3:


structs are not automatically immutable, but because of certain issues it is strongly recommended to make them immutable yourself. You may be thinking of a similar problem where you can't change the properties of a struct if the struct is itself being accessed as a property (one of the reasons why it is recommended to make them immutable.) Using your Test example:

public struct Test {
   public string str { get; set; }
   public int int1 { get; set; }
}

// This works:
Test value = new Test();
value.str = "asdf";
value.int1 = 5;

// But this does NOT work.
Test TestProperty { get; set; }

TestProperty.str = "asdf";
TestProperty.int1 = 5;

The reason the second part doesn't work is that you are only getting a value copy by saying TestProperty, and then you set the value of the copy's properties, rather than the one in your object.

To make your struct immutable you would do something like this:

public struct Test {
   readonly string mStr;
   readonly int mInt1;

   public string str { get { return mStr; } }
   public int int1 { get { return mInt1; } }

   public Test(string pStr, int pInt1) {
      mStr = pStr;
      mInt1 = pInt1;
   }
}

You can create instances of Test, you can read their properties, but you can't change their properties, except by making a new instance.




回答4:


Can definitely reassign new instance values to a struct. Immutability means that when you think you are changing the value, a new instance is created in memory and the previous copy is up for garbage collection.

Note that structs are immutable as a whole. Struct fields, in turn, can be mutable or immutable atomically. For your example, the string field is immutable, int is not.



来源:https://stackoverflow.com/questions/25171940/change-the-value-of-a-property-of-a-struct-in-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!