Immutability of structs [duplicate]

2019-01-03 09:45发布

Possible Duplicate:
Why are mutable structs evil?

I read it in lots of places including here that it's better to make structs as immutable.

What's the reason behind this? I see lots of Microsoft-created structs that are mutable, like the ones in xna. Probably there are many more in the BCL.

What are the pros and cons of not following this guideline?

9条回答
家丑人穷心不美
2楼-- · 2019-01-03 10:27

When you copy structs around you copy their contents, so if you modify a copied version the "original" will not be updated.

This is a source for errors, since even if you know that you fall into the trap of copying a struct (just by passing it to a method) and modifying the copy.

Just happened to me again last week, kept me an hour searching for a bug.

Keeping structs immutable prevents that ...

Other than that you need to make sure you have a really good reason to use structs in the first place - "optimization" or "I want something that allocates quickly on the stack" does not count as an answer. Marshaling or things where you depend on layout - ok, but you should not typically keep those structs around for very long, they are values not objects.

查看更多
戒情不戒烟
3楼-- · 2019-01-03 10:29

The big con is that things don't behave how you expect them to - particularly if the mutability comes from a mixture of the direct value and a reference type within it.

To be honest, I can't remember off the top of my head all the weird problems I've seen people come up with in newsgroups when they've used mutable structs - but those reasons certainly exist. Mutable structs cause problems. Stay away.

EDIT: I've just found an email I wrote a while ago on this topic. It elaborates just a little bit:

  • It's philosophically wrong: a struct should represent some sort of fundamental value. Those are basically immutable. You don't get to change the number 5. You can change a variable's value from 5 to 6, but you don't logically make a change to the value itself.

  • It's practically a problem: it creates lots of weird situations. It's particularly bad if it's mutable via an interface. Then you can start changing boxed values. Ick. I've seen a lot of newsgroup posts which are due to people trying to use mutable structs and running into issues. I saw a very strange LINQ example which was failing because List<T>.Enumerator is a struct, for example.

查看更多
ら.Afraid
4楼-- · 2019-01-03 10:32

There is nothing cheaper to manipulate than a mutable struct, which is why you often see it in high performance code like the graphics processing routines.

Unfortunately mutable structs don't play well with objects and properties, it is way too easy to modify a copy of a stuct instead of the struct itself. Thus they aren't appropriate for most of your code.

P.S. To avoid the cost of copying mutable structs, they are usually stored and passed in arrays.

查看更多
我欲成王,谁敢阻挡
5楼-- · 2019-01-03 10:33

You have asked for the pros and cons of not following the guideline that structs should be immutable.

Cons: The cons are well covered in existing answers, and most problems described are due to the same cause - unexpected behaviour due to structs' value semantics.

Pros: The main pro of using mutable structs can be performance. Obviously, this advice comes with all the usual caveats about optimisations: make sure that part of your code needs to be optimised and make sure any changes do actually optimise your code's performance via profiling.

For an excellent article discussing when you might want to use mutable structs, see Rico Mariani's Performance Quiz on Value-Based Programming (or more specifically, the answers).

查看更多
Juvenile、少年°
6楼-- · 2019-01-03 10:33

the reason you should make structs immutable is that they're ValueTypes, meaning that they are copied every time you pass them to a method.

So if, for example, you had a property that returned a struct, modifying the value of a field on that struct would be worthless, because the getter would return a copy of the struct, rather than a reference to the struct. I've seen this done in code, and it's often difficult to catch.

If you design your structs for immutability, you help the programmer avoid these mistakes.

查看更多
forever°为你锁心
7楼-- · 2019-01-03 10:35

A struct should generally represent a single unity of some kind. As such it doesn't make much sense to change one of the properties of the value, it makes more sense to create a completely new value if you want a value that is different somehow.

The semantics gets simpler when using immutable structs, and you avoid pitfalls like this:

// a struct
struct Interval {
   int From { get; set; }
   int To { get; set; }
}

// create a list of structs
List<Interval> intervals = new List<Interval>();

// add a struct to the list
intervals.Add(new Interval());

// try to set the values of the struct
intervals[0].From = 10;
intervals[0].To = 20;

The result is that the struct in the list is not changed at all. The expression Interval[0] copies the value of the struct from the list, then you change the property of the temporary value, but the value is never put back in the list.

Edit: Changed the example to use a list instead of an array.

查看更多
登录 后发表回答