Skip to content

Instantly share code, notes, and snippets.

@MirzaMerdovic
Created March 27, 2017 20:47
Show Gist options
  • Save MirzaMerdovic/2e47d02caca3a57fb0d00b95efa338a9 to your computer and use it in GitHub Desktop.
Save MirzaMerdovic/2e47d02caca3a57fb0d00b95efa338a9 to your computer and use it in GitHub Desktop.
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