Created
March 27, 2017 20:47
-
-
Save MirzaMerdovic/2e47d02caca3a57fb0d00b95efa338a9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This is a summary of this article: http://yizhang82.me/value-type-boxing | |
using System; | |
interface IAdd | |
{ | |
void Add(int val); | |
} | |
struct Foo : IAdd | |
{ | |
public int value; | |
void IAdd.Add(int val) | |
{ | |
value += val; | |
} | |
public void AddValue(int val) | |
{ | |
value += val; | |
} | |
public void Print(string msg) | |
{ | |
Console.WriteLine(msg + ":" + value); | |
} | |
} | |
class Program | |
{ | |
static void Add_WithoutConstraints<T>(ref T foo, int val) | |
{ | |
((IAdd)foo).Add(val); | |
} | |
static void Add_WithConstraints<T>(ref T foo, int val) where T : IAdd | |
{ | |
foo.Add(val); | |
} | |
static void Main(string[] args) | |
{ | |
Foo f = new Foo(); | |
f.value = 10; | |
f.Print("Initial Value"); | |
f.AddValue(10); | |
f.Print("After calling AddValue"); | |
((IAdd) f).Add(10); | |
f.Print("After calling IAdd.Add"); | |
Add_WithoutConstraints<Foo>(ref f, 10); | |
f.Print("After Add_WithoutConstrats"); | |
Add_WithConstraints<Foo>(ref f, 10); | |
f.Print("After Add_WithConstraints"); | |
} | |
} | |
---------------------------------------------------- | |
Result: | |
Initial Value:10 | |
After calling AddValue:20 | |
After calling IAdd.Add:20 | |
After Add_WithoutConstrats:20 | |
After Add_WithConstraints:30 | |
---------------------------------------------------- | |
In all method calls we have boxing and CLR will have to do the unboxing in order to call the underlaying method. | |
When method call happens it will be on the boxed value, and one would expect that value to be 20, but that boxed | |
value is only know to compiler, so it will be lost since it is unknown to CLR who will use the old value (10) | |
and hence we have a result of 20 for every method except: Add_WithConstraints<T>(ref f, int value). | |
Why? In "Add_WithConstraints" we have specified the constraint IAdd, which gives CLR enough information not to do | |
box/unbox which leads to not loosing the value and ultimately sets the result to what we expected in the frist | |
place, 30. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment