Use cases for boxing a value type in C#?

2019-03-19 06:11发布

There are cases when an instance of a value type needs to be treated as an instance of a reference type. For situations like this, a value type instance can be converted into a reference type instance through a process called boxing. When a value type instance is boxed, storage is allocated on the heap and the instance's value is copied into that space. A reference to this storage is placed on the stack. The boxed value is an object, a reference type that contains the contents of the value type instance.

Understanding .NET's Common Type System

In Wikipedia there is an example for Java. But in C#, what are some cases where one would have to box a value type? Or would a better/similar question be, why would one want to store a value type on the heap (boxed) rather than on the stack?

9条回答
手持菜刀,她持情操
2楼-- · 2019-03-19 06:52

I think a good example of boxing in c# occurs in the non-generic collections like ArrayList.

查看更多
Deceive 欺骗
3楼-- · 2019-03-19 06:54

I would recommend you 2 nice articles of Eric Lippert

http://blogs.msdn.com/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx

http://blogs.msdn.com/ericlippert/archive/2009/05/04/the-stack-is-an-implementation-detail-part-two.aspx

Here is the quote that I would 100% agree with

Using the stack for locals of value type is just an optimization that the CLR performs on your behalf. The relevant feature of value types is that they have the semantics of being copied by value, not that sometimes their deallocation can be optimized by the runtime.

In 99% applications developers should not care about why Value types are in stack and not in the heap and what performance gain could we have here. Juts have in mind very simple rules:

  1. Avoid boxing/unboxing when not necessary, use generics collections. Most problems occurs not when you define your own types, but when you use existing types inproperly (defined by Microsoft or your collegues)
  2. Make your value types simple. If you need to have a struct with 10-20 fields, I suppose you'ld better create a class. Imagine, all that fields will be copied each time when you occasionally pass it a function by value...
  3. I don't think it is very useful to have value types with reference type fields inside. Like struct with String and object fields.
  4. Define what type you need depending on required functionality, not on where it should be stored. Structs have limited functionality comparing to classes, so if struct cannot provide the required functionality, like default constructor, define class.
  5. If something can perform any actions with the data of other types, it is usually defined as a class. For structs operations with different types should be defined only if you can cast one type to another. Say you can add int to double because you can cast int to double.
  6. If something should be stateless, it is a class.
  7. When you are hesitating, use reference types. :-)

Any rules allows exclusions in special cases, but do not try to over-optimize.

p.s. I met some ASP.NET developers with 2-3 years experience who doesn't know the difference between stack and heap. :-( I would not hire such a person if I'm an interviewer, but not because boxing/unboxing could be a bottleneck in any of ASP.NET sites I've ever seen.

查看更多
三岁会撩人
4楼-- · 2019-03-19 07:04

There is almost never a good reason to deliberately box a value type. Almost always, the reason to box a value type is to store it in some collection that is not type aware. The old ArrayList, for example, is a collection of objects, which are reference types. The only way to collect, say, integers, is to box them as objects and pass them to ArrayList.

Nowadays, we have generic collections, so this is less of an issue.

查看更多
兄弟一词,经得起流年.
5楼-- · 2019-03-19 07:04

Below is some examples of boxing/unboxing

ArrayList ints = new ArrayList();
myInts.Add(1); // boxing
myInts.Add(2); // boxing

int myInt = (int)ints [0]; // unboxing

Console.Write("Value is {0}", myInt); // boxing
查看更多
姐就是有狂的资本
6楼-- · 2019-03-19 07:06

One example would when a method takes an object parameter and a value type must be passed in.

查看更多
干净又极端
7楼-- · 2019-03-19 07:07

One of the situations when this happens is for example if you have method that expect parameter of type object and you are passing in one of the primitive types, int for example. Or if you define parameter as 'ref' of type int.

查看更多
登录 后发表回答