Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>First, a short (and probably incomplete) primer on value types, reference types, and boxing.</p> <p>You can tell that something is a value type because changes made in a function do not persist outside the function. The value of the object is copied when the function is called, and thrown away at the end of that function.</p> <p>You can tell that something is a reference type because changes made in a function persist outside the function. The value of the object is not copied when the function is called, and exists after the end of that function.</p> <p>If something is boxed, a single copy is made, and seated within a reference type. It effectively changes from a value type to a reference type.</p> <p>Note that this all applies to instanced state, i.e. any non-static member data. Static members are not instanced state, and have nothing to do with reference types, value types, or boxing. Methods and properties that don't use instanced state (for example, ones that use only local variables or static member data) will not operate differently differently on reference types, value types, or when boxing occurs.</p> <p>Armed with that knowledge, here is how we can prove that <strong>boxing does occur when converting a struct to an interface (generic or not)</strong>:</p> <pre><code>using System; interface ISomeInterface&lt;T&gt; { void Foo(); T MyValue { get; } } struct SomeStruct : ISomeInterface&lt;int&gt; { public void Foo() { this.myValue++; } public int MyValue { get { return myValue; } } private int myValue; } class Program { static void SomeFunction(ISomeInterface&lt;int&gt; value) { value.Foo(); } static void Main(string[] args) { SomeStruct test1 = new SomeStruct(); ISomeInterface&lt;int&gt; test2 = test1; // Call with struct directly SomeFunction(test1); Console.WriteLine(test1.MyValue); SomeFunction(test1); Console.WriteLine(test1.MyValue); // Call with struct converted to interface SomeFunction(test2); Console.WriteLine(test2.MyValue); SomeFunction(test2); Console.WriteLine(test2.MyValue); } } </code></pre> <p>The output looks like this:</p> <blockquote> <p>0<br> 0<br> 1<br> 2 </p> </blockquote> <p>This means that boxing occurs only when doing the conversion:</p> <ul> <li>The first two calls do the boxing upon each call.</li> <li>The second two calls already have a boxed copy, and boxing does not occur upon each call.</li> </ul> <p>I won't bother duplicating all the code here, but if you change <code>ISomeInterface&lt;T&gt;</code> to <code>ISomeInterface</code>, you'll still have the same behavior.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload