Example: Use of Interfaces on Value Types
When considering the use of interfaces on a value type, often the first question asked is, "Can value types support interfaces?" The simple answer is yes; you can call the methods defined in the interface directly on the value type without incurring any overhead. The situation is different, however, if you call the methods through an interface reference. An interface references objects allocated on the garbage collected heap, and value types are normally allocated on the stackso how does this work? The answer is a familiar one: boxing.
Listing 2.9 demonstrates the use of events and properties in a user-defined interface, IPoint. This interface is implemented by a value type, Point, and an object type, EntryPoint, provides the entry point method. Similar to Listing 2.8, this program creates a value of the value type and then accesses its properties.
Listing 2.9 Using events and properties in a user-defined interface
using System; namespace InterfaceSample { public delegate void Changed(); interface IPoint { int X { get; set;} int Y { get; set;} } struct Point: IPoint { private int xValue, yValue; public int X { get { return xValue; } set { xValue = value; } } public int Y { get { return yValue; } set { yValue = value; } } } public class EntryPoint { public static int Main() { Point p = new Point(); p.X = p.Y = 42; IPoint ip = p; Console.WriteLine("X: {0}, Y: {1}", ip.X, ip.Y); return 0; } } }
Listing 2.9 produces the following output:
X: 42, Y: 42
The interesting point regarding this program is the use of the interface ip to access the properties of p when calling the WriteLine method. As Listing 2.9 is written, the interface ip can only refer to reference types and p is a value type, so p is silently boxed and ip references the boxed object, which contains a copy of p.