C# supports two major kinds of types: value types and reference types. Value types include simple types (e.g., char
, int
, and float
), enum types, and struct types. Reference types include class types, interface types, delegate types, and array types.
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.
The example
using System; class Class1 { public int Value = 0; } class Test { static void Main() { int val1 = 0; int val2 = val1; val2 = 123; Class1 ref1 = new Class1(); Class1 ref2 = ref1; ref2.Value = 123; Console.WriteLine("Values: {0}, {1}", val1, val2); Console.WriteLine("Refs: {0}, {1}", ref1.Value, ref2.Value); } }
shows this difference. The output of the program is
Values: 0, 123 Refs: 123, 123
The assignment to the local variable val1
does not impact the local variable val2
because both local variables are of a value type (int
) 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.
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
using System; public enum Color { Red, Blue, Green } public struct Point { public int x, y; } public interface IBase { void F(); } public interface IDerived: IBase { void G(); } public class A { protected void H() { Console.WriteLine("A.H"); } } public class B: A, IDerived { public void F() { Console.WriteLine("B.F, implementation of IDerived.F"); } public void G() { Console.WriteLine("B.G, implementation of IDerived.G"); } } public delegate void EmptyDelegate();
shows an example or two for each kind of type declaration. Later sections describe type declarations in greater detail.