[英]Another “Why shouldn't structs be mutable?” C#
I've read When should I use a struct instead of a class? 我读过什么时候应该使用结构而不是类? which references MSDN's guidance, which says: 参考MSDN的指导,其中说:
Do not define a structure unless the type has all of the following characteristics: 除非类型具有以下所有特征,否则不要定义结构:
- It logically represents a single value, similar to primitive types (integer, double, and so on). 它逻辑上表示单个值,类似于基本类型(整数,双精度等)。
- It has an instance size smaller than 16 bytes. 它的实例大小小于16个字节。
- It is immutable. 这是不可改变的。
- It will not have to be boxed frequently. 它不必经常装箱。
and Why are mutable structs “evil”? 为什么可变结构“邪恶”? has answer: 有答案:
Structs are value types which means they are copied when they are passed around. 结构是值类型,这意味着它们在传递时被复制。
I'm struggling to understand why I shouldn't just be conscious that structs need to be passed by reference, else changes made to the version passed through a function will not affect the original. 我很难理解为什么我不应该只是意识到结构需要通过引用传递,否则对通过函数传递的版本所做的更改不会影响原始版本。 Yes, I've had tons of bugs from this in the past, but now I'm experienced enough that I'm careful not to have it happen. 是的,我过去曾经有过很多错误,但是现在我经验丰富,我不小心不会发生这种错误。
I make exclusively games in C#, and variables for stuff in games need to change a lot. 我只使用C#制作游戏,游戏内容的变量需要改变很多。
Say I have a player character, represented by class "Player" in my game. 假设我有一个玩家角色,在我的游戏中由“玩家”类代表。 If Player has variables X and Y to say where it is, these would change a lot. 如果玩家有变量X和Y来说明它的位置,那么这些变化会很大。 I wouldn't want to create a new Player every time it moves, just to preserve immutability? 我不希望每次移动时创建一个新玩家,只是为了保持不变性? So my class should be mutable. 所以我的班级应该是可变的。 OK. 好。
But what if I want to store data about my entity. 但是,如果我想存储有关我的实体的数据,该怎么办? If I store its position on the screen in a Rectangle (x,y,w,h), should I make Rectangle a CLASS because it's going to be mutable? 如果我在Rectangle(x,y,w,h)中将其位置存储在屏幕上,我是否应该将Rectangle设为CLASS,因为它是可变的? It's just a logical collection of 4 variables, so a struct seems sensible as a container to me. 它只是4个变量的逻辑集合,因此结构对我来说似乎是合理的容器。
I also have "Colour" as a struct (r,g,b,a), but I have it as mutable because I might want to shift the alpha of things in the game to fade them in/out, or colour something red for a second when it gets hurt, without the overhead of calling "new Colour" every render call. 我也有“颜色”作为一个结构(r,g,b,a),但我有它可变,因为我可能想要改变游戏中的东西的α来淡入/淡出它们,或者将颜色变为红色一秒钟受到伤害,没有每次渲染调用调用“new Color”的开销。
I saw another post which said structs should be used if these conditions are met: 我看到另一个帖子,如果符合这些条件,应该使用结构:
- Is the main responsibility of the type data storage? 类型数据存储的主要责任是什么?
- Is its public interface defined entirely by properties that access or modify its data members? 它的公共接口是否完全由访问或修改其数据成员的属性定义?
- Are you sure your type will never have subclasses? 你确定你的类型永远不会有子类吗?
- Are you sure your type will never be treated polymorphically? 你确定你的类型永远不会被多态化处理吗?
The answer to this would be "yes" for the structs I use, but most of them would be mutable. 对于我使用的结构,这个问题的答案是肯定的,但是大多数结构都是可变的。
I'm confused about all of the conflicting advice here. 我对这里所有相互矛盾的建议感到困惑。 Are mutable structs OK for certain types of use, or am I designing my code all wrong? 对于某些类型的使用,可变结构是否正常,或者我设计的代码是错误的吗?
It's not just the chance of accidentally losing information: 这不仅仅是意外丢失信息的机会:
list.ForEach(item => item.X = 10);
// this code does nothing useful if item is a mutable struct
It's also the weird interaction between mutating methods and readonly
: 它也是变异方法和readonly
之间奇怪的相互作用 :
readonly MutableStruct m_field;
...
m_field.MutatingMethod(); // mutates a temporary copy rather than the field
But if you've determined through profiling that: 但是如果你通过剖析确定了:
Then mutable structs may be what you need. 然后可变结构可能是你需要的。 That's why they're in the language after all. 这就是为什么他们毕竟是这种语言的原因。
Speaking of game code, SharpDX is full of mutable structs ( example ) and methods that pass by reference. 说到游戏代码,SharpDX充满了可变结构( 示例 )和通过引用传递的方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.