Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
181 views
in Technique[技术] by (71.8m points)

c# - Why is it possible to instantiate a struct without the new keyword?

Why are we not forced to instantiate a struct, like when using a class?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Why are we not forced to instantiate a struct with "new", like when using a class?

When you "new" a reference type, three things happen. First, the memory manager allocates space from long term storage. Second, a reference to that space is passed to the constructor, which initializes the instance. Third, that reference is passed back to the caller.

When you "new" a value type, three things happen. First, the memory manager allocates space from short term storage. Second, the constructor is passed a reference to the short term storage location. After the constructor runs, the value that was in the short-term storage location is copied to the storage location for the value, wherever that happens to be. Remember, variables of value type store the actual value.

(Note that the compiler is allowed to optimize these three steps into one step if the compiler can determine that doing so never exposes a partially-constructed struct to user code. That is, the compiler can generate code that simply passes a reference to the final storage location to the constructor, thereby saving one allocation and one copy.)

So now we can address your question, which you actually have asked backwards. It would be better to ask:

Why are we forced to allocate a class with "new", instead of simply being able to initialize the fields as with a struct?

You have to allocate a class with "new" because of those three things on the list. You need new memory allocated from the long-term storage and you need to pass a reference to that storage to the constructor. "new" is the operator that knows how to do that.

You don't have to call "new" on a struct because there is no need to allocate the "final" storage; the final storage already exists. The new value is going to go somewhere, and you already have obtained that storage by some other means. Value types do not need a new allocation; all they need is initialization. All you need to do is ensure that the storage is properly initialized, and you can often do that without calling a constructor. Doing so of course means that you run the risk of having a variable of value type that can be observed to be in a partially initialized state by user code.

Summing up: calling a ctor is optional for value types because no new memory needs to be allocated when initializing an instance of a value type and because skipping the constructor call means that you get to skip a short-term allocation and a copy. The price you pay for that performance gain is that user code can see a partially initialized structure.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...