ECMA-334 C# Language Specification8.2: Types (informative) |
C# supports two 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); } } |
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 (the 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.
The lines
Console.WriteLine("Values: {0}, {1}", val1, val2); Console.WriteLine("Refs: {0}, {1}", ref1.Value, ref2.Value); |
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 virtual 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"); } override protected void H() { Console.WriteLine("B.H, override of A.H"); } } public delegate void EmptyDelegate(); |
In This Section: