2 <clause number="8.2" title="Types" informative="true">
3 <paragraph>C# supports two kinds of types: value types and reference types. Value types include simple types (e.g., <keyword>char</keyword>, <keyword>int</keyword>, and <keyword>float</keyword>), enum types, and struct types. Reference types include class types, interface types, delegate types, and array types. </paragraph>
4 <paragraph>Value types differ from reference types in that variables of the value types directly contain their data, whereas variables of the reference types store references to objects. With reference types, it is possible for two variables to reference the same object, and thus possible for operations on one variable to affect the object referenced by the other variable. With value types, the variables each have their own copy of the data, and it is not possible for operations on one to affect the other. </paragraph>
5 <paragraph>The example <code_example><![CDATA[
17 Class1 ref1 = new Class1();
20 Console.WriteLine("Values: {0}, {1}", val1, val2);
21 Console.WriteLine("Refs: {0}, {1}", ref1.Value, ref2.Value);
24 ]]></code_example>shows this difference. The output produced is <code_example><![CDATA[
27 ]]></code_example></paragraph>
28 <paragraph>The assignment to the local variable val1 does not impact the local variable val2 because both local variables are of a value type (the type <keyword>int</keyword>) and each local variable of a value type has its own storage. In contrast, the assignment ref2.Value = 123; affects the object that both ref1 and ref2 reference. </paragraph>
29 <paragraph>The lines <code_example><![CDATA[
30 Console.WriteLine("Values: {0}, {1}", val1, val2);
31 Console.WriteLine("Refs: {0}, {1}", ref1.Value, ref2.Value);
32 ]]></code_example>deserve further comment, as they demonstrate some of the string formatting behavior of Console.WriteLine, which, in fact, takes a variable number of arguments. The first argument is a string, which may contain numbered placeholders like {0} and {1}. Each placeholder refers to a trailing argument with {0} referring to the second argument, {1} referring to the third argument, and so on. Before the output is sent to the console, each placeholder is replaced with the formatted value of its corresponding argument. </paragraph>
33 <paragraph>Developers can define new value types through enum and struct declarations, and can define new reference types via class, interface, and delegate declarations. The example <code_example><![CDATA[
43 public interface IBase
47 public interface IDerived: IBase
53 protected virtual void H() {
54 Console.WriteLine("A.H");
57 public class B: A, IDerived
60 Console.WriteLine("B.F, implementation of IDerived.F");
63 Console.WriteLine("B.G, implementation of IDerived.G");
65 override protected void H() {
66 Console.WriteLine("B.H, override of A.H");
69 public delegate void EmptyDelegate();
70 ]]></code_example>shows an example of each kind of type declaration. Later sections describe type declarations in detail. </paragraph>