IComparable<(Of <(T>)>) Interface Defines a generalized comparison method that a value type or class implements to create a type-specific comparison

method for ordering instances. Namespace: System Assembly: mscorlib (in mscorlib.dll) Syntax Visual Basic (Declaration) Public Interface IComparable(Of T) Visual Basic (Usage) Dim instance As IComparable(Of T) C# public interface IComparable<T> Type Parameters T The type of objects to compare. Remarks This interface is implemented by types whose values can be ordered; for example, the numeric and string classes. A value type or class implements the CompareTo method to create a type-specific comparison method suitable for purposes such as sorting. Note: The IComparable<(Of <(T>)>) interface defines the CompareTo method, which determines the sort order of instances of the implementing type. The IEquatable<(Of <(T>)>) interface defines the Equals method, which determines the equality of instances of the implementing type. The IComparable<(Of <(T>)>) interface provides a strongly typed comparison method for ordering members of a generic collection object. Because of this, it is usually not called directly from developer code. Instead, it is called automatically by methods such as List<(Of <(T>)>)..::.Sort()()() and Add. Notes to Implementers: Replace the type parameter of the IComparable<(Of <(T>)>) interface with the type that is implementing this interface. Examples The following code example illustrates the implementation of IComparable for a simple Temperature object. The example creates a SortedList<(Of <(TKey, TValue>)>) collection of strings with Temperature object keys, and adds several pairs of temperatures and strings to the list out of sequence. In the call to the Add method, the SortedList<(Of <(TKey, TValue>)>) collection uses the IComparable<(Of <(T>)>) implementation to sort the list entries, which are then displayed in order of increasing temperature. Visual Basic Imports System Imports System.Collections.Generic Public Class Temperature Implements IComparable(Of Temperature) ' Implement the generic CompareTo method. In the Implements statement, ' specify the Temperature class for the type parameter of the ' generic IComparable interface. Use that type for the parameter ' of the CompareTo method. ' Public Overloads Function CompareTo(ByVal other As Temperature) As Integer _

Implements IComparable(Of Temperature).CompareTo ' The temperature comparison depends on the comparison of the ' the underlying Double values. Because the CompareTo method is ' strongly typed, it is not necessary to test for the correct ' object type. Return m_value.CompareTo(other.m_value) End Function ' The underlying temperature value. Protected m_value As Double = 0.0 Public ReadOnly Property Celsius() As Double Get Return m_value - 273.15 End Get End Property Public Property Kelvin() As Double Get Return m_value End Get Set(ByVal Value As Double) If value < 0.0 Then Throw New ArgumentException("Temperature cannot be less than absolute zero.") Else m_value = Value End If End Set End Property Public Sub New(ByVal degreesKelvin As Double) Me.Kelvin = degreesKelvin End Sub End Class Public Class Example Public Shared Sub Main() Dim temps As New SortedList(Of Temperature, String) ' Add entries to the sorted list, out of order. temps.Add(New Temperature(2017.15), "Boiling point of Lead") temps.Add(New Temperature(0), "Absolute zero") temps.Add(New Temperature(273.15), "Freezing point of water") temps.Add(New Temperature(5100.15), "Boiling point of Carbon") temps.Add(New Temperature(373.15), "Boiling point of water") temps.Add(New Temperature(600.65), "Melting point of Lead") For Each kvp As KeyValuePair(Of Temperature, String) In temps Console.WriteLine("{0} is {1} degrees Celsius.", kvp.Value, kvp.Key.Celsius) Next End Sub End Class ' This code example produces the following output: ' 'Absolute zero is -273.15 degrees Celsius.

'Freezing point of water is 0 degrees Celsius. 'Boiling point of water is 100 degrees Celsius. 'Melting point of Lead is 327.5 degrees Celsius. 'Boiling point of Lead is 1744 degrees Celsius. 'Boiling point of Carbon is 4827 degrees Celsius. ' C# using System; using System.Collections.Generic; public class Temperature : IComparable<Temperature> { // Implement the CompareTo method. For the parameter type, Use // the type specified for the type parameter of the generic // IComparable interface. // public int CompareTo(Temperature other) { // The temperature comparison depends on the comparison of the // the underlying Double values. Because the CompareTo method is // strongly typed, it is not necessary to test for the correct // object type. return m_value.CompareTo(other.m_value); } // The underlying temperature value. protected double m_value = 0.0; public double Celsius { get { return m_value - 273.15; } } public double Kelvin { get { return m_value; } set { if (value < 0.0) { throw new ArgumentException("Temperature cannot be less than absolute zero."); } else { m_value = value; } } } public Temperature(double degreesKelvin) {

} }

this.Kelvin = degreesKelvin;

public class Example { public static void Main() { SortedList<Temperature, string> temps = new SortedList<Temperature, string>(); // Add entries to the sorted list, out of order. temps.Add(new Temperature(2017.15), "Boiling point of Lead"); temps.Add(new Temperature(0), "Absolute zero"); temps.Add(new Temperature(273.15), "Freezing point of water"); temps.Add(new Temperature(5100.15), "Boiling point of Carbon"); temps.Add(new Temperature(373.15), "Boiling point of water"); temps.Add(new Temperature(600.65), "Melting point of Lead"); foreach( KeyValuePair<Temperature, string> kvp in temps ) { Console.WriteLine("{0} is {1} degrees Celsius.", kvp.Value, kvp.Key.Celsius); }

} }

/* This code example produces the following output: Absolute zero is -273.15 degrees Celsius. Freezing point of water is 0 degrees Celsius. Boiling point of water is 100 degrees Celsius. Melting point of Lead is 327.5 degrees Celsius. Boiling point of Lead is 1744 degrees Celsius. Boiling point of Carbon is 4827 degrees Celsius. */ IComparable<(Of <(T>)>) Interface Defines a generalized comparison method that a value type or class implements to create a type-specific comparison method for ordering instances. Namespace: System Assembly: mscorlib (in mscorlib.dll) Syntax Visual Basic (Declaration) Public Interface IComparable(Of T) Visual Basic (Usage) Dim instance As IComparable(Of T) C# public interface IComparable<T> Type Parameters T The type of objects to compare. Remarks

This interface is implemented by types whose values can be ordered; for example, the numeric and string classes. A value type or class implements the CompareTo method to create a type-specific comparison method suitable for purposes such as sorting. Note: The IComparable<(Of <(T>)>) interface defines the CompareTo method, which determines the sort order of instances of the implementing type. The IEquatable<(Of <(T>)>) interface defines the Equals method, which determines the equality of instances of the implementing type. The IComparable<(Of <(T>)>) interface provides a strongly typed comparison method for ordering members of a generic collection object. Because of this, it is usually not called directly from developer code. Instead, it is called automatically by methods such as List<(Of <(T>)>)..::.Sort()()() and Add. Notes to Implementers: Replace the type parameter of the IComparable<(Of <(T>)>) interface with the type that is implementing this interface. Examples The following code example illustrates the implementation of IComparable for a simple Temperature object. The example creates a SortedList<(Of <(TKey, TValue>)>) collection of strings with Temperature object keys, and adds several pairs of temperatures and strings to the list out of sequence. In the call to the Add method, the SortedList<(Of <(TKey, TValue>)>) collection uses the IComparable<(Of <(T>)>) implementation to sort the list entries, which are then displayed in order of increasing temperature. Visual Basic Imports System Imports System.Collections.Generic Public Class Temperature Implements IComparable(Of Temperature) ' Implement the generic CompareTo method. In the Implements statement, ' specify the Temperature class for the type parameter of the ' generic IComparable interface. Use that type for the parameter ' of the CompareTo method. ' Public Overloads Function CompareTo(ByVal other As Temperature) As Integer _ Implements IComparable(Of Temperature).CompareTo ' The temperature comparison depends on the comparison of the ' the underlying Double values. Because the CompareTo method is ' strongly typed, it is not necessary to test for the correct ' object type. Return m_value.CompareTo(other.m_value) End Function ' The underlying temperature value. Protected m_value As Double = 0.0 Public ReadOnly Property Celsius() As Double Get Return m_value - 273.15 End Get End Property Public Property Kelvin() As Double Get Return m_value

End Get Set(ByVal Value As Double) If value < 0.0 Then Throw New ArgumentException("Temperature cannot be less than absolute zero.") Else m_value = Value End If End Set End Property Public Sub New(ByVal degreesKelvin As Double) Me.Kelvin = degreesKelvin End Sub End Class Public Class Example Public Shared Sub Main() Dim temps As New SortedList(Of Temperature, String) ' Add entries to the sorted list, out of order. temps.Add(New Temperature(2017.15), "Boiling point of Lead") temps.Add(New Temperature(0), "Absolute zero") temps.Add(New Temperature(273.15), "Freezing point of water") temps.Add(New Temperature(5100.15), "Boiling point of Carbon") temps.Add(New Temperature(373.15), "Boiling point of water") temps.Add(New Temperature(600.65), "Melting point of Lead") For Each kvp As KeyValuePair(Of Temperature, String) In temps Console.WriteLine("{0} is {1} degrees Celsius.", kvp.Value, kvp.Key.Celsius) Next End Sub End Class ' This code example produces the following output: ' 'Absolute zero is -273.15 degrees Celsius. 'Freezing point of water is 0 degrees Celsius. 'Boiling point of water is 100 degrees Celsius. 'Melting point of Lead is 327.5 degrees Celsius. 'Boiling point of Lead is 1744 degrees Celsius. 'Boiling point of Carbon is 4827 degrees Celsius. ' C# using System; using System.Collections.Generic; public class Temperature : IComparable<Temperature> { // Implement the CompareTo method. For the parameter type, Use // the type specified for the type parameter of the generic // IComparable interface. // public int CompareTo(Temperature other) { // The temperature comparison depends on the comparison of the // the underlying Double values. Because the CompareTo method is

}

// strongly typed, it is not necessary to test for the correct // object type. return m_value.CompareTo(other.m_value);

// The underlying temperature value. protected double m_value = 0.0; public double Celsius { get { return m_value - 273.15; } } public double Kelvin { get { return m_value; } set { if (value < 0.0) { throw new ArgumentException("Temperature cannot be less than absolute zero."); } else { m_value = value; } } } public Temperature(double degreesKelvin) { this.Kelvin = degreesKelvin; }

}

public class Example { public static void Main() { SortedList<Temperature, string> temps = new SortedList<Temperature, string>(); // Add entries to the sorted list, out of order. temps.Add(new Temperature(2017.15), "Boiling point of Lead"); temps.Add(new Temperature(0), "Absolute zero"); temps.Add(new Temperature(273.15), "Freezing point of water"); temps.Add(new Temperature(5100.15), "Boiling point of Carbon"); temps.Add(new Temperature(373.15), "Boiling point of water"); temps.Add(new Temperature(600.65), "Melting point of Lead"); foreach( KeyValuePair<Temperature, string> kvp in temps )

{ } } }

Console.WriteLine("{0} is {1} degrees Celsius.", kvp.Value, kvp.Key.Celsius);

/* This code example produces the following output: Absolute zero is -273.15 degrees Celsius. Freezing point of water is 0 degrees Celsius. Boiling point of water is 100 degrees Celsius. Melting point of Lead is 327.5 degrees Celsius. Boiling point of Lead is 1744 degrees Celsius. Boiling point of Carbon is 4827 degrees Celsius. */ IConvertible The System.IConvertible interface defines methods for converting the value of the implementing reference or value type to a Common Language Runtime (CLR) type with an equivalent value. [edit]Syntax [edit]Declaration syntax [ComVisibleAttribute(true)] [CLSCompliantAttribute(false)] public interface IConvertible[edit]Method syntax UNDER CONSTRUCTION

[edit]Usage The IConvertible Interface defines methods to convert an instance of your class' object to a CLR type. It may appear a daunting task at first to implement all of these methods. However, there are some tricks that can be used to make it a whole lot easier: Throw InvalidCastException if it would not make sense to convert to this type Define a private method to calculate the class' value Use the Convert class to convert the desired numeric value to the other CLR types [edit]Vector Class class Vector : IConvertible { private double m_X; private double m_Y; private double m_Z; public Vector(double x, double y, double z) { m_X = x; m_Y = y; m_Z = z; } public double getX() { return m_X; }

public double getY() { return m_Y; } public double getZ() { return m_Z; } private Double calculateMagnitude() { Double magnitudeThis = 0; magnitudeThis += Math.Pow(m_X, 2); magnitudeThis += Math.Pow(m_Y, 2); magnitudeThis += Math.Pow(m_Z, 2); magnitudeThis = Math.Sqrt(magnitudeThis); } return magnitudeThis;

#region IConvertible Members public TypeCode GetTypeCode() { return TypeCode.Object; } public bool ToBoolean(IFormatProvider provider) { //Could just throw exception //What about returning true if magnitude > 0 return (calculateMagnitude() > 0) ? true : false; } public byte ToByte(IFormatProvider provider) { return Convert.ToByte(calculateMagnitude()); } public char ToChar(IFormatProvider provider) { throw new InvalidCastException("Cannot cast Vector to Char"); } public DateTime ToDateTime(IFormatProvider provider) { throw new InvalidCastException("Cannot cast Vector to DateTime"); } public decimal ToDecimal(IFormatProvider provider) {

}

return Convert.ToDecimal(calculateMagnitude());

public double ToDouble(IFormatProvider provider) { return calculateMagnitude(); } public short ToInt16(IFormatProvider provider) { return Convert.ToInt16(calculateMagnitude()); } public int ToInt32(IFormatProvider provider) { return Convert.ToInt32(calculateMagnitude()); } public long ToInt64(IFormatProvider provider) { return Convert.ToInt64(calculateMagnitude()); } public sbyte ToSByte(IFormatProvider provider) { return Convert.ToSByte(calculateMagnitude()); } public float ToSingle(IFormatProvider provider) { return Convert.ToSingle(calculateMagnitude()); } public string ToString(IFormatProvider provider) { return "Magnitude: " + calculateMagnitude().ToString(provider); } public object ToType(Type conversionType, IFormatProvider provider) { return Convert.ChangeType(calculateMagnitude(), conversionType); } public ushort ToUInt16(IFormatProvider provider) { return Convert.ToUInt16(calculateMagnitude()); } public uint ToUInt32(IFormatProvider provider) { return Convert.ToUInt32(calculateMagnitude()); } public ulong ToUInt64(IFormatProvider provider) { return Convert.ToUInt64(calculateMagnitude()); }

#endregion }[edit]Example Although you can call the 'To' methods of the instance of the class individually, it is more normal to use the Convert class which in turn will call the instances' methods. This example shows iterating through all of the defined CLR types by using a method to return the type. Before returning the type the method stores where it is, so it can continue execution from that point when it is called again. This is done with the yield keyword which just simplifies the readability and maintainability of the code. static void Main(string[] args) { Vector myV = new Vector(1.5, 1.5, 1.5); foreach (TypeCode currentType in getCode()) { try { Console.WriteLine("{0}: " + Convert.ChangeType(myV, currentType), currentType.ToString()); } catch (InvalidCastException) { Console.WriteLine("{0}: Invalid Cast ", currentType.ToString()); } }

}

static IEnumerable<TypeCode> getCode() { yield return TypeCode.Boolean; yield return TypeCode.Byte; yield return TypeCode.Char; yield return TypeCode.DateTime; yield return TypeCode.DBNull; yield return TypeCode.Decimal; yield return TypeCode.Double; yield return TypeCode.Empty; yield return TypeCode.Int16; yield return TypeCode.Int32; yield return TypeCode.Int64; yield return TypeCode.Object; yield return TypeCode.SByte; yield return TypeCode.Single; yield return TypeCode.String; yield return TypeCode.UInt16; yield return TypeCode.UInt32; yield return TypeCode.UInt64; }

IConvertible Interface Defines methods that convert the value of the implementing reference or value type to a common language runtime type that has an equivalent value. This API is not CLS-compliant. Namespace: System Assembly: mscorlib (in mscorlib.dll) Syntax Visual Basic (Declaration) <ComVisibleAttribute(True)> _ <CLSCompliantAttribute(False)> _ Public Interface IConvertible Visual Basic (Usage) Dim instance As IConvertible C# [ComVisibleAttribute(true)] [CLSCompliantAttribute(false)] public interface IConvertible Remarks This interface provides methods to convert the value of an instance of an implementing type to a common language runtime type that has an equivalent value. The common language runtime types are Boolean, SByte, Byte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Decimal, DateTime, Char, and String. If there is no meaningful conversion to a common language runtime type, then a particular interface method implementation throws InvalidCastException. For example, if this interface is implemented on a Boolean type, the implementation of the ToDateTime method throws an exception because there is no meaningful DateTime equivalent to a Boolean type.

The common language runtime typically exposes the IConvertible interface through the Convert class. The common language runtime also uses the IConvertible interface internally, in explicit interface implementations, to simplify the code used to support conversions in the Convert class and basic common language runtime types. In addition to the IConvertible interface, the .NET Framework provides classes called type converters for converting user-defined data types to other data types. For more information, see the Generalized Type Conversion topic. Examples The following code sample demonstrates an implementation of IConvertible for a Complex number class, allowing it to be cast first as a Double and then calling the static Convert members on that Double. Visual Basic Imports System Module Module1 Public Class Complex Implements IConvertible Private x As Double Private y As Double Public Sub New(ByVal x As Double, ByVal y As Double) Me.x = x Me.y = y End Sub 'New Public Function GetTypeCode() As TypeCode Implements IConvertible.GetTypeCode Return TypeCode.Object End Function Function ToBoolean(ByVal provider As IFormatProvider) As Boolean Implements IConvertible.ToBoolean If x <> 0 Or y <> 0 Then Return True Else Return False End If End Function Function GetDoubleValue() As Double Return Math.Sqrt((x * x + y * y)) End Function Function ToByte(ByVal provider As IFormatProvider) As Byte Implements IConvertible.ToByte Return Convert.ToByte(GetDoubleValue()) End Function Function ToChar(ByVal provider As IFormatProvider) As Char Implements IConvertible.ToChar Return Convert.ToChar(GetDoubleValue()) End Function

Function ToDateTime(ByVal provider As IFormatProvider) As DateTime Implements IConvertible.ToDateTime Return Convert.ToDateTime(GetDoubleValue()) End Function Function ToDecimal(ByVal provider As IFormatProvider) As Decimal Implements IConvertible.ToDecimal Return Convert.ToDecimal(GetDoubleValue()) End Function Function ToDouble(ByVal provider As IFormatProvider) As Double Implements IConvertible.ToDouble Return GetDoubleValue() End Function Function ToInt16(ByVal provider As IFormatProvider) As Short Implements IConvertible.ToInt16 Return Convert.ToInt16(GetDoubleValue()) End Function Function ToInt32(ByVal provider As IFormatProvider) As Integer Implements IConvertible.ToInt32 Return Convert.ToInt32(GetDoubleValue()) End Function Function ToInt64(ByVal provider As IFormatProvider) As Long Implements IConvertible.ToInt64 Return Convert.ToInt64(GetDoubleValue()) End Function Function ToSByte(ByVal provider As IFormatProvider) As SByte Implements IConvertible.ToSByte Return Convert.ToSByte(GetDoubleValue()) End Function Function ToSingle(ByVal provider As IFormatProvider) As Single Implements IConvertible.ToSingle Return Convert.ToSingle(GetDoubleValue()) End Function Overloads Function ToString(ByVal provider As IFormatProvider) As String Implements IConvertible.ToString Return "( " + x.ToString() + " , " + y.ToString() + " )" End Function Function ToType(ByVal conversionType As Type, ByVal provider As IFormatProvider) As Object Implements IConvertible.ToType Return Convert.ChangeType(GetDoubleValue(), conversionType) End Function Function ToUInt16(ByVal provider As IFormatProvider) As UInt16 Implements IConvertible.ToUInt16 Return Convert.ToUInt16(GetDoubleValue()) End Function

Function ToUInt32(ByVal provider As IFormatProvider) As UInt32 Implements IConvertible.ToUInt32 Return Convert.ToUInt32(GetDoubleValue()) End Function Function ToUInt64(ByVal provider As IFormatProvider) As UInt64 Implements IConvertible.ToUInt64 Return Convert.ToUInt64(GetDoubleValue()) End Function End Class Sub Main() Dim testComplex As New Complex(4, 7) WriteObjectInfo(testComplex) WriteObjectInfo(Convert.ToBoolean(testComplex)) WriteObjectInfo(Convert.ToDecimal(testComplex)) WriteObjectInfo(Convert.ToString(testComplex)) End Sub Sub WriteObjectInfo(ByVal testObject As Object) Dim typeCode As TypeCode = Type.GetTypeCode(testObject.GetType()) Select Case typeCode Case typeCode.Boolean Console.WriteLine("Boolean: {0}", testObject) Case typeCode.Double Console.WriteLine("Double: {0}", testObject) Case Else Console.WriteLine("{0}: {1}", typeCode.ToString(), testObject) End Select End Sub End Module C# using System; namespace ConsoleApplication2 { /// Class that implements IConvertible class Complex : IConvertible { double x; double y; public Complex(double x, double y) { this.x = x; this.y = y; } public TypeCode GetTypeCode()

{ }

return TypeCode.Object;

bool IConvertible.ToBoolean(IFormatProvider provider) { if( (x != 0.0) || (y != 0.0) ) return true; else return false; } double GetDoubleValue() { return Math.Sqrt(x*x + y*y); } byte IConvertible.ToByte(IFormatProvider provider) { return Convert.ToByte(GetDoubleValue()); } char IConvertible.ToChar(IFormatProvider provider) { return Convert.ToChar(GetDoubleValue()); } DateTime IConvertible.ToDateTime(IFormatProvider provider) { return Convert.ToDateTime(GetDoubleValue()); } decimal IConvertible.ToDecimal(IFormatProvider provider) { return Convert.ToDecimal(GetDoubleValue()); } double IConvertible.ToDouble(IFormatProvider provider) { return GetDoubleValue(); } short IConvertible.ToInt16(IFormatProvider provider) { return Convert.ToInt16(GetDoubleValue()); } int IConvertible.ToInt32(IFormatProvider provider) { return Convert.ToInt32(GetDoubleValue()); } long IConvertible.ToInt64(IFormatProvider provider) { return Convert.ToInt64(GetDoubleValue()); }

sbyte IConvertible.ToSByte(IFormatProvider provider) { return Convert.ToSByte(GetDoubleValue()); } float IConvertible.ToSingle(IFormatProvider provider) { return Convert.ToSingle(GetDoubleValue()); } string IConvertible.ToString(IFormatProvider provider) { return "( " + x.ToString() + " , " + y.ToString() + " )"; } object IConvertible.ToType(Type conversionType, IFormatProvider provider) { return Convert.ChangeType(GetDoubleValue(),conversionType); } ushort IConvertible.ToUInt16(IFormatProvider provider) { return Convert.ToUInt16(GetDoubleValue()); } uint IConvertible.ToUInt32(IFormatProvider provider) { return Convert.ToUInt32(GetDoubleValue()); } ulong IConvertible.ToUInt64(IFormatProvider provider) { return Convert.ToUInt64(GetDoubleValue()); } } /// <summary> /// Summary description for Class1. /// </summary> class Class1 { static void Main(string[] args) { Complex testComplex = new Complex(4,7);

WriteObjectInfo(testComplex); WriteObjectInfo(Convert.ToBoolean(testComplex)); WriteObjectInfo(Convert.ToDecimal(testComplex)); WriteObjectInfo(Convert.ToString(testComplex)); } static void WriteObjectInfo(object testObject) { TypeCode typeCode = Type.GetTypeCode( testObject.GetType() );

switch( typeCode ) { case TypeCode.Boolean: Console.WriteLine("Boolean: {0}", testObject); break; case TypeCode.Double: Console.WriteLine("Double: {0}", testObject); break; default: Console.WriteLine("{0}: {1}", typeCode.ToString(), testObject); break; } } } }

IDisposable The System.IDisposable interface defines a method of releasing unmanaged resources which have been allocated. Syntax Declaration syntax [ComVisibleAttribute(true)] public interface IDisposable[edit]Method syntax The Dispose method performs tasks defined by the application associated with releasing or resetting unmanaged resources. Resources like database connections, handles, files, and streams which are held by an instance of the class implementing this interface. void Dispose () Usage Although this looks like a simple interface, it brings with it some complications due to digging into Garbage Collector (GC) territory. These complications can be minimized by sticking to these simple rules: Set unmanaged objects to null Call the Dispose methods of managed objects Stop the Garbage Collector from calling finalize methods on managed objects class MyClass : IDisposable { FileStream myStream; //large object public MyClass (string filePath) { myStream = new FileStream (filePath, FileAccess.ReadWrite); } public void Dispose() { myStream.Dispose(); //remove myStream from the GC finalize queue GC.SuppressFinalize(myStream); } }You should only use these classes inside a try-catch-finally statement or a using statement.

using(MyClass testObj = new MyClass("File.txt")) { //use testObj } //testObj is out of scope here as it has been disposed Garbage Collection The .NET Framework's garbage collector manages the allocation and release of memory for your application. Each time you use the newoperator to create an object, the runtime allocates memory for the object from the managed heap. As long as address space is available in the managed heap, the runtime continues to allocate space for new objects. However, memory is not infinite. Eventually the garbage collector must perform a collection in order to free some memory. The garbage collector's optimizing engine determines the best time to perform a collection, based upon the allocations being made. When the garbage collector performs a collection, it checks for objects in the managed heap that are no longer being used by the application and performs the necessary operations to reclaim their memory. This section describes how the garbage collector automatically manages the allocation and release of memory for the managed objects in your application. In addition, it describes the recommended design pattern to use to properly clean up any unmanaged resources that your application creates. Note: In the .NET Framework version 1.0, the common language runtime (CLR) has a separate memory manager for the large object heap. Under some circumstances this memory manager does not return unused memory to the operating system, and in a few cases it does not make the memory available for garbage collection. This results in failure to allocate memory due to virtual address space fragmentation. In the .NET Framework versions 1.1 and 2.0, the large object heap is composed of contiguous areas of memory called heap segments, properly aligned to minimize virtual memory fragmentation. During garbage collection, the space reclaimed from large objects is consolidated and placed in a free list. Heap segments containing only free list items are freed and the memory is returned to the operating system. These changes to the large object heap have effectively eliminated memory allocation failures caused by this form of virtual address space fragmentation. Important Note: On servers with more than 2GB of memory, it may be necessary to specify the /3GB switch in the boot.ini file to avoid apparent out-of-memory issues while memory is still available to the system. In This Section Developer Backgrounds in Memory Management Describes the adjustments developers, who have traditionally used Visual Basic, C++, and COM, should make when moving to managed code. Finalize Methods and Destructors Describes how Finalize methods and destructors allow an object to perform necessary cleanup operations before the garbage collector automatically reclaims the object's memory. Weak References Describes features that permit the garbage collector to collect an object while still allowing the application to access that object. Induced Collections Describes how to reclaim objects immediately or at the next optimal time. Latency Modes Describes the modes that determine the intrusiveness of garbage collection. Optimization for Shared Web Hosting

Describes how to optimize garbage collection on servers shared by hosting several small Web sites. Garbage Collection Notifications Describes how to determine when a full garbage collection is approaching and when it has completed. Cleaning Up Unmanaged Resources Describes the recommended design pattern for cleaning up unmanaged resources. Reference System..::.GC Provides methods for interacting with the system garbage collector. Object..::.Finalize Allows an object to attempt to free resources and perform other cleanup operations before the garbage collector reclaims the object. System..::.IDisposable Provides the functionality for a resource class. IDisposable Interface Defines a method to release allocated resources. Namespace: System Assembly: mscorlib (in mscorlib.dll) Syntax Visual Basic (Declaration) <ComVisibleAttribute(True)> _ Public Interface IDisposable Visual Basic (Usage) Dim instance As IDisposable C# [ComVisibleAttribute(true)] public interface IDisposable Remarks The primary use of this interface is to release unmanaged resources. The garbage collector automatically releases the memory allocated to a managed object when that object is no longer used. However, it is not possible to predict when garbage collection will occur. Furthermore, the garbage collector has no knowledge of unmanaged resources such as window handles, or open files and streams. Use the Dispose method of this interface to explicitly release unmanaged resources in conjunction with the garbage collector. The consumer of an object can call this method when the object is no longer needed. Important Note: C++ programmers should read Destructors and Finalizers in Visual C++. In the .NET Framework version, the C++ compiler provides support for implementing deterministic disposal of resources and does not allow direct implementation of the Dispose method. It is a version-breaking change to add the IDisposable interface to an existing class, because it changes the semantics of the class. For a detailed discussion about how this interface and the Object..::.Finalize method are used, see the Garbage Collection and Implementing a Dispose Method topics. Calling the IDisposable Interface When calling a class that implements the IDisposable interface, use the try/finally pattern to make sure that unmanaged resources are disposed of even if an exception interrupts your application.

Note that you can use the using statement (Using in Visual Basic) instead of the try/finally pattern. For more information, see the Using Statement (Visual Basic) documentation or the using Statement (C# Reference) documentation. Examples The following example demonstrates how to create a resource class that implements the IDisposable interface. Visual Basic Copy Code Imports System Imports System.ComponentModel ' The following example demonstrates how to create ' a resource class that implements the IDisposable interface ' and the IDisposable.Dispose method. Public Class DisposeExample ' A class that implements IDisposable. ' By implementing IDisposable, you are announcing that ' instances of this type allocate scarce resources. Public Class MyResource Implements IDisposable ' Pointer to an external unmanaged resource. Private handle As IntPtr ' Other managed resource this class uses. Private component As component ' Track whether Dispose has been called. Private disposed As Boolean = False ' The class constructor. Public Sub New(ByVal handle As IntPtr) Me.handle = handle End Sub ' Implement IDisposable. ' Do not make this method virtual. ' A derived class should not be able to override this method. Public Overloads Sub Dispose() Implements IDisposable.Dispose Dispose(True) ' This object will be cleaned up by the Dispose method. ' Therefore, you should call GC.SupressFinalize to ' take this object off the finalization queue ' and prevent finalization code for this object ' from executing a second time. GC.SuppressFinalize(Me) End Sub ' Dispose(bool disposing) executes in two distinct scenarios. ' If disposing equals true, the method has been called directly ' or indirectly by a user's code. Managed and unmanaged resources ' can be disposed. ' If disposing equals false, the method has been called by the ' runtime from inside the finalizer and you should not reference ' other objects. Only unmanaged resources can be disposed. Private Overloads Sub Dispose(ByVal disposing As Boolean) ' Check to see if Dispose has already been called. If Not Me.disposed Then ' If disposing equals true, dispose all managed

' and unmanaged resources. If disposing Then ' Dispose managed resources. component.Dispose() End If ' Call the appropriate methods to clean up ' unmanaged resources here. ' If disposing is false, ' only the following code is executed. CloseHandle(handle) handle = IntPtr.Zero ' Note disposing has been done. disposed = True End If End Sub ' Use interop to call the method necessary ' to clean up the unmanaged resource. <System.Runtime.InteropServices.DllImport("Kernel32")> _ Private Shared Function CloseHandle(ByVal handle As IntPtr) As [Boolean] End Function ' This finalizer will run only if the Dispose method ' does not get called. ' It gives your base class the opportunity to finalize. ' Do not provide finalize methods in types derived from this class. Protected Overrides Sub Finalize() ' Do not re-create Dispose clean-up code here. ' Calling Dispose(false) is optimal in terms of ' readability and maintainability. Dispose(False) MyBase.Finalize() End Sub End Class Public Shared Sub Main() ' Insert code here to create ' and use the MyResource object. End Sub End Class C# using System; using System.ComponentModel; // The following example demonstrates how to create // a resource class that implements the IDisposable interface // and the IDisposable.Dispose method. public class DisposeExample { // A base class that implements IDisposable. // By implementing IDisposable, you are announcing that

// instances of this type allocate scarce resources. public class MyResource: IDisposable { // Pointer to an external unmanaged resource. private IntPtr handle; // Other managed resource this class uses. private Component component = new Component(); // Track whether Dispose has been called. private bool disposed = false; // The class constructor. public MyResource(IntPtr handle) { this.handle = handle; } // Implement IDisposable. // Do not make this method virtual. // A derived class should not be able to override this method. public void Dispose() { Dispose(true); // This object will be cleaned up by the Dispose method. // Therefore, you should call GC.SupressFinalize to // take this object off the finalization queue // and prevent finalization code for this object // from executing a second time. GC.SuppressFinalize(this); } // Dispose(bool disposing) executes in two distinct scenarios. // If disposing equals true, the method has been called directly // or indirectly by a user's code. Managed and unmanaged resources // can be disposed. // If disposing equals false, the method has been called by the // runtime from inside the finalizer and you should not reference // other objects. Only unmanaged resources can be disposed. private void Dispose(bool disposing) { // Check to see if Dispose has already been called. if(!this.disposed) { // If disposing equals true, dispose all managed // and unmanaged resources. if(disposing) { // Dispose managed resources. component.Dispose(); } // Call the appropriate methods to clean up // unmanaged resources here. // If disposing is false, // only the following code is executed. CloseHandle(handle); handle = IntPtr.Zero; // Note disposing has been done.

disposed = true; } } // Use interop to call the method necessary // to clean up the unmanaged resource. [System.Runtime.InteropServices.DllImport("Kernel32")] private extern static Boolean CloseHandle(IntPtr handle); // Use C# destructor syntax for finalization code. // This destructor will run only if the Dispose method // does not get called. // It gives your base class the opportunity to finalize. // Do not provide destructors in types derived from this class. ~MyResource() { // Do not re-create Dispose clean-up code here. // Calling Dispose(false) is optimal in terms of // readability and maintainability. Dispose(false); }

}

} public static void Main() { // Insert code here to create // and use the MyResource object. }

Implementing a Dispose Method The pattern for disposing an object, referred to as a dispose pattern, imposes order on the lifetime of an object. A type's Disposemethod should release all the resources that it owns. It should also release all resources owned by its base types by calling its parent type's Dispose method. The parent type's Dispose method should release all resources that it owns and in turn call its parent type's Dispose method, propagating this pattern through the hierarchy of base types. To help ensure that resources are always cleaned up appropriately, a Dispose method should be callable multiple times without throwing an exception. There is no performance benefit in implementing the Dispose method on types that use only managed resources (such as arrays) because they are automatically reclaimed by the garbage collector. Use the Dispose method primarily on managed objects that use native resources and on COM objects that are exposed to the .NET Framework. Managed objects that use native resources (such as the FileStream class) implement the IDisposable interface. Important Note: C++ programmers should not use this topic. Instead, see Destructors and Finalizers in Visual C++. In the .NET Framework version 2.0, the C++ compiler provides support for implementing deterministic disposal of resources and does not allow direct implementation of the Dispose method. A Dispose method should call the SuppressFinalize method for the object it is disposing. If the object is currently on the finalization queue, SuppressFinalize prevents its Finalize method from being called. Remember that executing a Finalize method is costly to performance. If your Dispose method has already done the work to clean up the object, then it is not necessary for the garbage collector to call the object's Finalize method. The code example provided for the GC..::.KeepAlive method shows how aggressive garbage collection can cause a finalizer to run while a member of the reclaimed object is still executing. It is a good idea to call the KeepAlive method at the end of a lengthy Dispose method.

Example The following code example shows the recommended design pattern for implementing a Dispose method for classes that encapsulate unmanaged resources. Resource classes are typically derived from complex native classes or APIs and must be customized accordingly. Use this code pattern as a starting point for creating a resource class and provide the necessary customization based on the resources you are encapsulating. Visual Basic Imports System Imports System.IO Class Program Public Shared Sub Main() Try ' Initialize a Stream resource to pass ' to the DisposableResource class. Console.Write("Enter filename and its path: ") Dim fileSpec As String = Console.ReadLine Dim fs As FileStream = File.OpenRead(fileSpec) Dim TestObj As DisposableResource = New DisposableResource(fs) ' Use the resource. TestObj.DoSomethingWithResource() ' Dispose theresource. TestObj.Dispose() Catch e As FileNotFoundException Console.WriteLine(e.Message) End Try End Sub End Class ' This class shows how to use a disposable resource. ' The resource is first initialized and passed to ' the constructor, but it could also be ' initialized in the constructor. ' The lifetime of the resource does not ' exceed the lifetime of this instance. ' This type does not need a finalizer because it does not ' directly create a native resource like a file handle ' or memory in the unmanaged heap. Public Class DisposableResource Implements IDisposable Private _resource As Stream Private _disposed As Boolean ' The stream passed to the constructor ' must be readable and not null. Public Sub New(ByVal stream As Stream) MyBase.New() If (stream Is Nothing) Then Throw New ArgumentNullException("Stream is null.") End If If Not stream.CanRead Then

Throw New ArgumentException("Stream must be readable.") End If _resource = stream Dim objTypeName As String = _resource.GetType.ToString _disposed = False End Sub ' Demonstrates using the resource. ' It must not be already disposed. Public Sub DoSomethingWithResource() If _disposed Then Throw New ObjectDisposedException("Resource was disposed.") End If ' Show the number of bytes. Dim numBytes As Integer = CType(_resource.Length, Integer) Console.WriteLine("Number of bytes: {0}", numBytes.ToString) End Sub Public Overloads Sub Dispose() Implements IDisposable.Dispose Dispose(True) ' Use SupressFinalize in case a subclass ' of this type implements a finalizer. GC.SuppressFinalize(Me) End Sub Protected Overridable Overloads Sub Dispose(ByVal disposing As Boolean) If Not _disposed Then ' If you need thread safety, use a lock around these ' operations, as well as in your methods that use the resource. If disposing Then If (Not (_resource) Is Nothing) Then _resource.Dispose() End If Console.WriteLine("Object disposed.") End If ' Indicates that the instance has been disposed. _resource = Nothing _disposed = True End If End Sub End Class C# using System; using System.IO; class Program { static void Main() { try {

// Initialize a Stream resource to pass // to the DisposableResource class. Console.Write("Enter filename and its path: "); string fileSpec = Console.ReadLine(); FileStream fs = File.OpenRead(fileSpec); DisposableResource TestObj = new DisposableResource(fs); // Use the resource. TestObj.DoSomethingWithResource(); // Dispose the resource. TestObj.Dispose(); } catch (FileNotFoundException e) { Console.WriteLine(e.Message); } } // // // // // // // // // }

This class shows how to use a disposable resource. The resource is first initialized and passed to the constructor, but it could also be initialized in the constructor. The lifetime of the resource does not exceed the lifetime of this instance. This type does not need a finalizer because it does not directly create a native resource like a file handle or memory in the unmanaged heap.

public class DisposableResource : IDisposable { private Stream _resource; private bool _disposed; // The stream passed to the constructor // must be readable and not null. public DisposableResource(Stream stream) { if (stream == null) throw new ArgumentNullException("Stream in null."); if (!stream.CanRead) throw new ArgumentException("Stream must be readable."); _resource = stream; _disposed = false; } // Demonstrates using the resource. // It must not be already disposed. public void DoSomethingWithResource() { if (_disposed) throw new ObjectDisposedException("Resource was disposed.");

// Show the number of bytes. int numBytes = (int) _resource.Length; Console.WriteLine("Number of bytes: {0}", numBytes.ToString()); } public void Dispose() { Dispose(true); // Use SupressFinalize in case a subclass // of this type implements a finalizer. GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { // If you need thread safety, use a lock around these // operations, as well as in your methods that use the resource. if (!_disposed) { if (disposing) { if (_resource != null) _resource.Dispose(); Console.WriteLine("Object disposed."); } // Indicate that the instance has been disposed. _resource = null; _disposed = true;

} } }

Implementing a Dispose Method The pattern for disposing an object, referred to as a dispose pattern, imposes order on the lifetime of an object. A type's Disposemethod should release all the resources that it owns. It should also release all resources owned by its base types by calling its parent type's Dispose method. The parent type's Dispose method should release all resources that it owns and in turn call its parent type's Dispose method, propagating this pattern through the hierarchy of base types. To help ensure that resources are always cleaned up appropriately, a Dispose method should be callable multiple times without throwing an exception. There is no performance benefit in implementing the Dispose method on types that use only managed resources (such as arrays) because they are automatically reclaimed by the garbage collector. Use the Dispose method primarily on managed objects that use native resources and on COM objects that are exposed to the .NET Framework. Managed objects that use native resources (such as the FileStream class) implement the IDisposable interface. Important Note: C++ programmers should not use this topic. Instead, see Destructors and Finalizers in Visual C++. In the .NET Framework version 2.0, the C++ compiler provides support for implementing deterministic disposal of resources and does not allow direct implementation of the Dispose method. A Dispose method should call the SuppressFinalize method for the object it is disposing. If the object is currently on the finalization queue, SuppressFinalize prevents its Finalize method from being called. Remember

that executing a Finalize method is costly to performance. If your Dispose method has already done the work to clean up the object, then it is not necessary for the garbage collector to call the object's Finalize method. The code example provided for the GC..::.KeepAlive method shows how aggressive garbage collection can cause a finalizer to run while a member of the reclaimed object is still executing. It is a good idea to call the KeepAlive method at the end of a lengthy Dispose method. Example The following code example shows the recommended design pattern for implementing a Dispose method for classes that encapsulate unmanaged resources. Resource classes are typically derived from complex native classes or APIs and must be customized accordingly. Use this code pattern as a starting point for creating a resource class and provide the necessary customization based on the resources you are encapsulating. Visual Basic Imports System Imports System.IO Class Program Public Shared Sub Main() Try ' Initialize a Stream resource to pass ' to the DisposableResource class. Console.Write("Enter filename and its path: ") Dim fileSpec As String = Console.ReadLine Dim fs As FileStream = File.OpenRead(fileSpec) Dim TestObj As DisposableResource = New DisposableResource(fs) ' Use the resource. TestObj.DoSomethingWithResource() ' Dispose theresource. TestObj.Dispose() Catch e As FileNotFoundException Console.WriteLine(e.Message) End Try End Sub End Class ' This class shows how to use a disposable resource. ' The resource is first initialized and passed to ' the constructor, but it could also be ' initialized in the constructor. ' The lifetime of the resource does not ' exceed the lifetime of this instance. ' This type does not need a finalizer because it does not ' directly create a native resource like a file handle ' or memory in the unmanaged heap. Public Class DisposableResource Implements IDisposable Private _resource As Stream Private _disposed As Boolean ' The stream passed to the constructor ' must be readable and not null.

Public Sub New(ByVal stream As Stream) MyBase.New() If (stream Is Nothing) Then Throw New ArgumentNullException("Stream is null.") End If If Not stream.CanRead Then Throw New ArgumentException("Stream must be readable.") End If _resource = stream Dim objTypeName As String = _resource.GetType.ToString _disposed = False End Sub ' Demonstrates using the resource. ' It must not be already disposed. Public Sub DoSomethingWithResource() If _disposed Then Throw New ObjectDisposedException("Resource was disposed.") End If ' Show the number of bytes. Dim numBytes As Integer = CType(_resource.Length, Integer) Console.WriteLine("Number of bytes: {0}", numBytes.ToString) End Sub Public Overloads Sub Dispose() Implements IDisposable.Dispose Dispose(True) ' Use SupressFinalize in case a subclass ' of this type implements a finalizer. GC.SuppressFinalize(Me) End Sub Protected Overridable Overloads Sub Dispose(ByVal disposing As Boolean) If Not _disposed Then ' If you need thread safety, use a lock around these ' operations, as well as in your methods that use the resource. If disposing Then If (Not (_resource) Is Nothing) Then _resource.Dispose() End If Console.WriteLine("Object disposed.") End If ' Indicates that the instance has been disposed. _resource = Nothing _disposed = True End If End Sub End Class C# using System; using System.IO; class Program

{ static void Main() { try { // Initialize a Stream resource to pass // to the DisposableResource class. Console.Write("Enter filename and its path: "); string fileSpec = Console.ReadLine(); FileStream fs = File.OpenRead(fileSpec); DisposableResource TestObj = new DisposableResource(fs); // Use the resource. TestObj.DoSomethingWithResource(); // Dispose the resource. TestObj.Dispose(); } catch (FileNotFoundException e) { Console.WriteLine(e.Message); } } // // // // // // // // // }

This class shows how to use a disposable resource. The resource is first initialized and passed to the constructor, but it could also be initialized in the constructor. The lifetime of the resource does not exceed the lifetime of this instance. This type does not need a finalizer because it does not directly create a native resource like a file handle or memory in the unmanaged heap.

public class DisposableResource : IDisposable { private Stream _resource; private bool _disposed; // The stream passed to the constructor // must be readable and not null. public DisposableResource(Stream stream) { if (stream == null) throw new ArgumentNullException("Stream in null."); if (!stream.CanRead) throw new ArgumentException("Stream must be readable."); _resource = stream; _disposed = false; }

// Demonstrates using the resource. // It must not be already disposed. public void DoSomethingWithResource() { if (_disposed) throw new ObjectDisposedException("Resource was disposed."); // Show the number of bytes. int numBytes = (int) _resource.Length; Console.WriteLine("Number of bytes: {0}", numBytes.ToString()); } public void Dispose() { Dispose(true); // Use SupressFinalize in case a subclass // of this type implements a finalizer. GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { // If you need thread safety, use a lock around these // operations, as well as in your methods that use the resource. if (!_disposed) { if (disposing) { if (_resource != null) _resource.Dispose(); Console.WriteLine("Object disposed."); } // Indicate that the instance has been disposed. _resource = null; _disposed = true;

} } }

IEquatable The System.IEquatable interface defines a type-safe method for creating a type-specific method to determine equality of instances. Note: This interface is new in the .NET Framework version 2.0. Syntax Declaration syntax public interface IEquatable<T>[edit]Method syntax The Equals method indicates whether the current object is equal to another object of the same type. bool Equals ( T other )where other is an object of the same type to be compared with this object. Returns true if the current object is equal to the parameter object; otherwise, false. Example

Vector myVA = new Vector(1.5, 1.5, 1.5); Vector myVB = new Vector(1.5, 1.5, 1.5); if (myVA == myVB) { Console.WriteLine("myVA = myVB"); } else { Console.WriteLine("myVA != myVB"); } if (myVA.Equals(myVB)) { Console.WriteLine("myVA = myVB"); } else { Console.WriteLine("myVA != myVB"); } class Vector: IEquatable<Vector> { private double m_X; private double m_Y; private double m_Z; public Vector(double x, double y, double z) { m_X = x; m_Y = y; m_Z = z; } public double getX() { return m_X; } public double getY() { return m_Y; } public double getZ() { return m_Z; } #region IEquatable<Vector> Members public bool Equals(Vector other) { bool result = false; if (this.m_X.Equals(other.getX()) &&

{ } }

this.m_Y.Equals(other.getY()) && this.m_Z.Equals(other.getZ())) result = true;

return result; #endregion } Result myVA != myVB myVA = myVB The reason for the first result is because the == compares the value stored in the variables myVA and myVB. Because these represent instances of classes they are reference types, so the values are memory addresses of where the actual object is stored in the heap. Therefore they can never be identical unless they actually point to the same object. The second result is from the Equals() method, this returns the correct result as the class has compared the actual values. IEquatable.Equals vs. System.Object.Equals The IEquatable.Equals method is very similar to Object.Equals. However, IEquatable.Equals is type-safe and generic—requiring no boxing and unboxing. IEquatable vs. IComparable At first glance, the IEquatable interface appears very similar to the IComparable interface. But, whereas IEquatable returns a bool representing only whether the instances are equal or not, IComparable returns an int indicating how the instances differ—whether smaller, equal or larger. IEquatable(T) Interface Defines a generalized method that a value type or class implements to create a type-specific method for determining equality of instances. Namespace: System Assembly: mscorlib (in mscorlib.dll) Syntax Visual Basic (Declaration) Public Interface IEquatable(Of T) Visual Basic (Usage) Dim instance As IEquatable(Of T) C# public interface IEquatable<T> Type Parameters T The type of objects to compare. Remarks This interface is implemented by types whose values can be equated (for example, the numeric and string classes). A value type or class implements the Equals method to create a type-specific method suitable for determining equality of instances. Note: The IComparable(T) interface defines the CompareTo method, which determines the sort order of instances of the implementing type. The IEquatable(T) interface defines the Equals method, which determines the equality of instances of the implementing type.

The IEquatable(T) interface is used by generic collection objects such as Dictionary(TKey, TValue), List(T), and LinkedList(T) when testing for equality in such methods as Contains, IndexOf, LastIndexOf, and Remove. It should be implemented for any object that might be stored in a generic collection. Notes to Implementers: Replace the type parameter of the IEquatable(T) interface with the type that is implementing this interface. If you implement IEquatable(T), you should also override the base class implementations of Object..::.Equals(Object) and GetHashCode so that their behavior is consistent with that of the IEquatable(T)..::.Equals method. If you do override Object..::.Equals(Object), your overridden implementation is also called in calls to the static Equals(System.Object, System.Object) method on your class. This ensures that all invocations of the Equals method return consistent results. Examples See the example for the IEquatable(T)..::.Equals method. IFormattable The System.IFormattable interface define a method for formatting the value of an object into a string representation. Syntax Declaration syntax [ComVisibleAttribute(true)] public interface IFormattable[edit]Method syntax The ToString method formats the value of the current instance using the specified format. string ToString ( string format, IFormatProvider formatProvider )where format specifies the format to be used; formatProvider specifies the IFormatProvider to use in formatting the value. If null, the numeric format information from the current locale setting of the operating system is used. IFormatProvider Interface Provides a mechanism for retrieving an object to control formatting. Namespace: System Assembly: mscorlib (in mscorlib.dll) Syntax Visual Basic (Declaration) <ComVisibleAttribute(True)> _ Public Interface IFormatProvider Visual Basic (Usage) Dim instance As IFormatProvider C# [ComVisibleAttribute(true)] public interface IFormatProvider Remarks Formatting methods convert the value of a type to the string representation of that value. Parsing methods convert the string representation of a value to a type with that value. These methods use the GetFormat method of types that implement the IFormatProvider interface to obtain an object that supplies information used in the formatting or parsing operation. The IFormatProvider interface imposes no requirements or restrictions on the information that is supplied. A type that implements the IFormatProvider interface typically supplies culture-specific information. For example, the IFormatProvider interface is implemented by the NumberFormatInfo, DateTimeFormatInfo, and

CultureInfo classes. The NumberFormatInfo class provides information that is used to format numbers, such as the currency, thousands separator, and decimal separator symbols for a particular culture. The DateTimeFormatInfo class provides information that is used to format dates and times, such as the date and time separator symbols for a particular culture. The CultureInfo class provides both a NumberFormatInfo object and a DateTimeFormatInfo object for a particular culture. IFormatProvider implementations are typically passed as parameters to methods that perform custom formatting or parsing operations. Methods that perform custom formatting operations include String..::.Format(IFormatProvider, String, array<Object>[]()[]) and various ToString instance methods. Methods that perform custom parsing operations include the Parse and TryParse methods of date, time, and numeric types. Examples The following example illustrates the use of a class that implements the IFormatProvider interface and the GetFormat method. The AcctNumberFormat class converts an Int64 value that represents an account number to a formatted 12-digit account number. Its GetFormat method returns a reference to the current AcctNumberFormat instance if the formatType parameter refers to a class that implements ICustomFormatter; otherwise, GetFormat returns nullNothingnullptra null reference (Nothing in Visual Basic). Visual Basic Public Class AcctNumberFormat : Implements IFormatProvider, ICustomFormatter Private Const ACCT_LENGTH As Integer = 12 Public Function GetFormat(formatType As Type) As Object _ Implements IFormatProvider.GetFormat If formatType Is GetType(ICustomFormatter) Then Return Me Else Return Nothing End If End Function Public Function Format(fmt As String, arg As Object, formatProvider As IFormatProvider) As String _ Implements ICustomFormatter.Format ' Convert argument to a string. Dim result As String = arg.ToString() ' If account number is less than 12 characters, pad with leading zeroes. If result.Length < ACCT_LENGTH Then result = result.PadLeft(ACCT_LENGTH, "0"c) ' If account number is more than 12 characters, truncate to 12 characters. If result.Length > ACCT_LENGTH Then result = Left(result, ACCT_LENGTH) ' Support G and H format specifiers. If String.IsNullOrEmpty(fmt) Then fmt = "G" If fmt.ToUpper = "G" Return result ' Add hyphens for H format specifier. Else If fmt.ToUpper = "H" Return Left(result, 5) & "-" & Mid(result, 6, 3) & "-" & Right(result, 4) ' Throw an exception for any other format specifier. Else Throw New FormatException(String.Format("{0} is not a valid format string.", fmt)) End If End Function End Class

C# public class AcctNumberFormat : IFormatProvider, ICustomFormatter { private const int ACCT_LENGTH = 12; public object GetFormat(Type formatType) { if (formatType == typeof(ICustomFormatter)) return this; else return null; } public string Format(string fmt, object arg, IFormatProvider formatProvider) { // Convert argument to a string. string result = arg.ToString(); // If account number is less than 12 characters, pad with leading zeroes. if (result.Length < ACCT_LENGTH) result = result.PadLeft(ACCT_LENGTH, '0'); // If account number is more than 12 characters, truncate to 12 characters. if (result.Length > ACCT_LENGTH) result = result.Substring(0, ACCT_LENGTH); // Support G and H format specifiers. if (String.IsNullOrEmpty(fmt)) fmt = "G"; if (fmt.ToUpper() == "G") return result; // Add hyphens for H format specifier. else if (fmt.ToUpper() == "H") return result.Substring(0, 5) + "-" + result.Substring(5, 3) + "-" + result.Substring(8); // Return string representation of argument for any other formatting code. else throw new FormatException(String.Format("{0} is not a valid format string.", fmt));

} }

The class that implements IFormatProvider can then be used in a call to a formatting and parsing operation. For example, the following code calls the String..::.Format(IFormatProvider, String, array<Object>[]()[]) method to generate a string that contains a formatted 12-digit account number. Visual Basic Module TestFormatting Public Sub Main() Dim acctNumber As Long acctNumber = 104254567890 Console.WriteLine(String.Format(New Console.WriteLine(String.Format(New acctNumber = 14567890 Console.WriteLine(String.Format(New Console.WriteLine(String.Format(New acctNumber = 18779887654111 Console.WriteLine(String.Format(New AcctNumberFormat, "{0:H}", acctNumber)) AcctNumberFormat, "{0}", acctNumber)) AcctNumberFormat, "{0:H}", acctNumber)) AcctNumberFormat, "{0}", acctNumber)) AcctNumberFormat, "{0:H}", acctNumber))

Console.WriteLine(String.Format(New AcctNumberFormat, "{0}", acctNumber)) End Sub End Module ' The example displays the following output: ' 10425-456-7890 ' 104254567890 ' 00001-456-7890 ' 000014567890 ' 18779-887-6541 ' 187798876541 C# public class TestFormatting { public static void Main() { long acctNumber; acctNumber = 104254567890; Console.WriteLine(String.Format(new Console.WriteLine(String.Format(new acctNumber = 14567890; Console.WriteLine(String.Format(new Console.WriteLine(String.Format(new acctNumber = 18779887654111; Console.WriteLine(String.Format(new Console.WriteLine(String.Format(new AcctNumberFormat(), "{0:H}", acctNumber)); AcctNumberFormat(), "{0}", acctNumber)); AcctNumberFormat(), "{0:H}", acctNumber)); AcctNumberFormat(), "{0}", acctNumber)); AcctNumberFormat(), "{0:H}", acctNumber)); AcctNumberFormat(), "{0}", acctNumber));

} } // The example displays the following output: // 10425-456-7890 // 104254567890 // 00001-456-7890 // 000014567890 // 18779-887-6541 // 187798876541

IFormattable Interface Provides functionality to format the value of an object into a string representation. Namespace: System Assembly: mscorlib (in mscorlib.dll) Syntax Visual Basic (Declaration) <ComVisibleAttribute(True)> _ Public Interface IFormattable Visual Basic (Usage) Dim instance As IFormattable C# [ComVisibleAttribute(true)] public interface IFormattable Remarks IFormattable is implemented by the base data types. A format describes the appearance of an object when it is converted to a string. A format can be either standard or custom. A standard format takes the form Axx, where A is an alphabetic character called the format specifier, and xx is a nonnegative integer called the precision specifier. The format specifier controls the

type of formatting applied to the value being represented as a string. The precision specifier controls the number of significant digits or decimal places in the string, if applicable. A custom format consists of one or more alphabetic characters that together define a single format string. When a format includes symbols that vary by culture, such as the currency symbol represented by the "C" and "c" standard numeric format specifiers, a formatting object (in the case of the "C" and "c" specifiers, a NumberFormatInfo object) supplies the actual characters used in the string representation. A method might include a parameter to pass an IFormatProvider object that supplies a formatting object, or the method might use the default formatting object, which contains the symbol definitions for the current thread. The current thread typically uses the same set of symbols used system-wide by default. Notes to Implementers: Classes that require more control over the formatting of strings than Object..::.ToString provides should implement IFormattable, whose ToString method uses the current thread's CurrentCulture property. A class that implements IFormattable must support the "G" (general) formatting code. Besides the "G" code, the class can define the list of formatting codes that it supports. Examples The following example demonstrates how to define a type that implements the IFormattable interface. The example also shows how to call the ToString method of the IFormattable interface. Visual Basic Public Class Point : Implements IFormattable Dim x, y As Integer Public Sub New(x As Integer, y As Integer) Me.x = x Me.y = y End Sub Public Overrides Function ToString() As String Return ToString(Nothing, Nothing) End Function Public Overloads Function ToString(format As String) As String Return ToString(format, Nothing) End Function Public Overloads Function ToString(format As String, _ fp As IFormatProvider) As String _ Implements IFormattable.ToString If String.IsNullOrEmpty(format) Then format = "G" ' If G format specifier is passed, display like this: (x, y). If format.ToLower() = "g" Then _ Return String.Format("({0}, {1})", x, y) ' For "x" formatting, return just the x value as a string If format.ToLower = "x" Then _ Return x.ToString() ' For "y" formatting, return just the y value as a string If format.ToLower = "y" Then _ Return y.ToString() ' For any unrecognized format, throw an exception. Throw New FormatException(String.Format("Invalid format string: '{0}'.", format)) End Function

End Class Public Module App Public Sub Main() ' Create the object. Dim p As New Point(5, 98) ' Test ToString with no formatting. Console.WriteLine("This is my point: " + p.ToString()) ' Use custom formatting style "x" Console.WriteLine("The point's x value is {0:x}", p) ' Use custom formatting style "y" Console.WriteLine("The point's y value is {0:y}", p) Try ' Use an invalid format; FormatException should be thrown here. Console.WriteLine("Invalid way to format a point: {0:XYZ}", p) Catch e As FormatException Console.WriteLine("The last line could not be displayed: {0}", e.Message) End Try End Sub End Module ' ' ' ' ' ' This code produces the following output. This is my point: (5, 98) The point's x value is 5 The point's y value is 98 The last line could not be displayed: Invalid format string: 'XYZ'.

C# using System; class Point : IFormattable { public int x, y; public Point(int x, int y) { this.x = x; this.y = y; } public override String ToString() { return ToString(null, null); } public String ToString(String format, IFormatProvider fp) { if (String.IsNullOrEmpty(format)) format = "G"; // If G format specifier is passed, display like this: (x, y). if (format.ToLower() == "g") return String.Format("({0}, {1})", x, y); // For "x" formatting, return just the x value as a string if (format.ToLower() == "x") return x.ToString();

// For "y" formatting, return just the y value as a string if (format.ToLower() == "y") return y.ToString(); // For any unrecognized format, throw an exception. throw new FormatException(String.Format("Invalid format string: '{0}'.", format)); } }

public sealed class App { static void Main() { // Create the object. Point p = new Point(5, 98); // Test ToString with no formatting. Console.WriteLine("This is my point: " + p.ToString()); // Use custom formatting style "x" Console.WriteLine("The point's x value is {0:x}", p); // Use custom formatting style "y" Console.WriteLine("The point's y value is {0:y}", p); try { // Use an invalid format; FormatException should be thrown here. Console.WriteLine("Invalid way to format a point: {0:XYZ}", p); } catch (FormatException e) { Console.WriteLine("The last line could not be displayed: {0}", e.Message); } } // // // // // // } This code produces the following output. This is my point: (5, 98) The point's x value is 5 The point's y value is 98 The last line could not be displayed: Invalid format string: 'XYZ'

INullableValue The System.INullableValue interface defines the fundamental value and existence properties for nullable types. However, it has been removed from .NET 2.0; because, nullables are now an intrinsic type in the CLR. Syntax Declaration syntax [ComVisibleAttribute(true)] public interface INullableValue[edit]Method syntax The INullableValue interface defines the following methods: The HasValue method indicates whether a nullable type has a defined value. bool HasValue { get; }The Value method gets the value of the nullable type. Object Value { get; }

INullableValue work around Instead, code like the following may be used: if (t.IsGenericType() && (t.GetGenericTypeDefinition() == typeof(System.Nullable<>)) {} Implement .NET Framework interfaces .NET Framework interfaces .NET 2.0 made available generic, type-safe versions of many interfaces. Where available, the generic version should be used to promote type safety. The non-generic versions are still available for backward compatibility. ICloneable IComparable IConvertible IDisposable IEquatable IFormattable INullableValue interface An interface contains only the signatures of methods, properties, events or indexers. The implementation of the members is done in the class or struct that implements the interface, as shown in the following example: Example C# interface ISampleInterface { void SampleMethod(); } class ImplementationClass : ISampleInterface { // Explicit interface member implementation: void ISampleInterface.SampleMethod() { // Method implementation. } static void Main() { // Declare an interface instance. ISampleInterface obj = new ImplementationClass(); // Call the member. obj.SampleMethod();

} }

An interface can be a member of a namespace or a class and can contain signatures of the following members: Methods Properties Indexers Events

An interface can inherit from one or more base interfaces. When a base type list contains a base class and interfaces, the base class must come first in the list. A class that implements an interface can explicitly implement members of that interface. An explicitly implemented member cannot be accessed through a class instance, but only through an instance of the interface. The following example demonstrates interface implementation. In this example, the interface contains the property declaration and the class contains the implementation. C# interface IPoint { // Property signatures: int x { get; set; } int y { get; set; }

}

class Point : IPoint { // Fields: private int _x; private int _y; // Constructor: public Point(int x, int y) { _x = x; _y = y; } // Property implementation: public int x { get { return _x; } set { _x = value; } } public int y { get { return _y;

} }

} set { _y = value; }

class MainClass { static void PrintPoint(IPoint p) { Console.WriteLine("x={0}, y={1}", p.x, p.y); } static void Main() { Point p = new Point(2, 3); Console.Write("My Point: "); PrintPoint(p); }

} // Output: My Point: x=2, y=3

Interfaces and Abstract Classes Interfaces An interface is a reference type containing only abstract members. These can be events, indexers, methods or properties, but only the member declarations. A class implementing an interface must provide the implementation of the interface members. An interface cannot contain constants, constructors, data fields, destructors, static members or other interfaces. Interface member declarations are implicitly public. Declaration [attributes] [modifiers] interface identifier [:base-type[,]] { body [;] }The attributes is optional and is used to hold additional declarative information. The modifier is optional. The allowed modifiers are public and internal, unless nested inside a class, then the allowed modifiers are public, protected, private and internal. If no modifier is supplied then a default of internal is used. The keyword interface must be followed by an identifier that names the interface. The base-type of an interface can be zero or more interfaces. When more than one base-type is used, then this is a comma-separated list of base-types. The body contains the member declarations. Implementation An interface is defined using the keyword interface. It is common practice to start all interface names with a capital I. For example: public interface IVehicle { void Start(); void Drive(); void Park(); void ChangeGear(int gear); void SwitchOff();

}In order to implement the interface, every method must be implemented in the class, else a compiler error will ensue. public class Vehicle : IVehicle { public void Start() { Console.WriteLine("The vehicle has been started"); } public void Drive() { Console.WriteLine("The vehicle is being driven"); } public void Park() { Console.WriteLine("The vehicle is being parked"); } public void ChangeGear(int gear) { Console.WriteLine("Gear changed to " + gear.ToString()); } public void SwitchOff() { Console.WriteLine("The vehicle has been switched off"); } }If a class implements more that one interface and the two interfaces have methods named the same, then each method must be implemented unless they have the same definition in which case only one implementation is needed to implement the methods. Here is a sample application (written in C# Express) showing the code above. More information can be found in the 70-536 section - Implement .NET Framework interfaces - including how to get Visual Studio to fill in most of the code for you. Abstract classes Like an interface, you cannot implement an instance of an abstract class, however you can implement methods, fields, and properties in the abstract class that can be used by the child class. For example, we could create an abstract class for all vehicle to inherit from: public abstract class Vehicle { public void Start() { Console.WriteLine("The vehicle has been started"); } public abstract void Drive(); public abstract void Park(); public abstract void ChangeGear(int gear); public void SwitchOff() {

Console.WriteLine("The vehicle has been switched off"); } }So each class that inherits from Vehicle will already be able to use the methods Start and SwitchOff, but they must implement Drive, Park and ChangeGear. So if we were to implement a Car class, it may look something like this. public class Car : Vehicle { public Car() { } public override void Drive() { Console.WriteLine("The car is being driven"); } public override void Park() { Console.WriteLine("The car is being parked"); } public override void ChangeGear(int gear) { Console.WriteLine("The car changed gear changed to " + gear.ToString()); } }The override keyword tells the compiler that this method was defined in the base class. Summary An Interface cannot implement methods. An abstract class can implement methods. An Interface can only inherit from another Interface. An abstract class can inherit from a class and one or more interfaces. An Interface cannot contain fields. An abstract class can contain fields. An Interface can contain property definitions. An abstract class can implement a property. An Interface cannot contain constructors or destructors. An abstract class can contain constructors or destructors. An Interface can be inherited from by structures. An abstract class cannot be inherited from by structures. An Interface can support multiple inheritance. An abstract class cannot support multiple inheritance. Interfaces Interfaces are defined by using the interface keyword, as shown in the following example: C# interface IEquatable<T> {

}

bool Equals(T obj);

Interfaces describe a group of related functionalities that can belong to any class or struct. Interfaces can consist of methods, properties, events, indexers, or any combination of those four member types. An interface cannot contain fields. Interfaces members are automatically public. When a class or struct is said to inherit an interface, it means that the class or struct provides an implementation for all of the members defined by the interface. The interface itself provides no functionality that a class or struct can inherit in the way that base class functionality can be inherited. However, if a base class implements an interface, the derived class inherits that implementation. Classes and structs can inherit from interfaces in a manner similar to how classes can inherit a base class or struct, with two exceptions: A class or struct can inherit more than one interface. When a class or struct inherits an interface, it inherits only the method names and signatures, because the interface itself contains no implementations. For example: C# public class Car : IEquatable<Car> { public string Make {get; set;} public string Model { get; set; } public string Year { get; set; } // Implementation of IEquatable<T> interface public bool Equals(Car car) { if (this.Make == car.Make && this.Model == car.Model && this.Year == car.Year) { return true; } else return false; }

}

To implement an interface member, the corresponding member on the class must be public, non-static, and have the same name and signature as the interface member. Properties and indexers on a class can define extra accessors for a property or indexer defined on an interface. For example, an interface may declare a property with a get accessor, but the class implementing the interface can declare the same property with both a get and set accessor. However, if the property or indexer uses explicit implementation, the accessors must match. Interfaces and interface members are abstract; interfaces do not provide a default implementation. For more information, see Abstract and Sealed Classes and Class Members. The IEquatable<(Of <(T>)>) interface announces to the user of the object that the object can determine whether it is equal to other objects of the same type, and the user of the interface does not have to know how this is implemented. Interfaces can inherit other interfaces. It is possible for a class to inherit an interface multiple times, through base classes or interfaces it inherits. In this case, the class can only implement the interface one time, if it is declared as part of the new class. If the inherited interface is not declared as part of the new class, its implementation is provided by the base class that declared it. It is possible for a base class to implement interface members using virtual members; in that case, the class inheriting the interface can change the interface behavior by overriding the virtual members. For more information about virtual members, see Polymorphism. Interfaces Overview

An interface has the following properties: An interface is like an abstract base class: any non-abstract type inheriting the interface must implement all its members. An interface cannot be instantiated directly. Interfaces can contain events, indexers, methods and properties. Interfaces contain no implementation of methods. Classes and structs can inherit from more than one interface. An interface can itself inherit from multiple interfaces. Iterators Iterators are an alternative to implementing IEnumerable. They are new in C# 2.0 and greatly reduce the complexity of providing an enumerator for a collection. When using an iterator, the compiler generates the IEnumerator class at build time. The keyword yield is used with a return statement to return a single item at a time. Each yield return corresponds to getting the current item. Then when the next item is requested, the compiler resumes the execution after the last yield return was called. In reality, the execution of the method does not begin at the beginning of the method each time. The compiler turns the single yield method into an entire IEnumerator class with its own state, MoveNext and Current. However, when implementing, do not focus on how the compiler accomplishes its task. Instead, simply yield one item at a time in the order desired using whatever technique is easiest. Code examples Iterate over some constant values public IEnumerable Values(){ yield yield yield yield yield yield yield yield yield yield return return return return return return return return return return 2; 55; 34; 324; 1; 7; 98; 34; 4; 11;

}Iterate through an internal array private int[] items; //... public IEnumerable Items(){ for (int i = 0; i < items.Length; i++){ yield return items[i]; } }Iterate through n prime numbers public IEnumerable Primes( int max ){ for (int i = 0; i < max; i++){ if( IsPrime( i ) ){ yield return i; }

} }Iterate forever // This has no end // It will always return Hello after every MoveNext // However, it is not an infinite loop // The one who uses the enumerator determines // whether to keep calling MoveNext public IEnumerable EternalEcho(){ while( true ){ yield return "Hello"; } } Generic Usage To promote type safety it is recommended that you use the generic IEnumerable form via IEnumerable<T>. As with all other generic classes, when you use them you are moving a possible error from run-time to compile/design-time. Iterating with foreach static void Main(string[] args) { foreach (TypeCode currentType in getCode()) { //Do Stuff } } Non-Generic You may want to do this at some point, it will compile, but can the caller handle it. If using a foreach loop then a cast occurs for each item. Depending on how you use the object inside the foreach loop you may have exceptions being thrown as 55000 is not an enumerated TypeCode. static IEnumerable getCode() { yield return TypeCode.Boolean; yield return TypeCode.Byte; yield return 55000; yield return TypeCode.Char; }[edit]Generic The compiler sees that this could cause problems and does not compile it. static IEnumerable<TypeCode> getCode() { yield return TypeCode.Boolean; yield return TypeCode.Byte; yield return 55000; yield return TypeCode.Char; }If you are 100% sure that it is what you want to do you could cast it. But only if you must! static IEnumerable<TypeCode> getCode() { yield return TypeCode.Boolean; yield return TypeCode.Byte; //You can persuade the compiler but you may get yourself into problems!

yield return (TypeCode) 55000; yield return TypeCode.Char; } Iterators An iterator is a method, get accessor, or operator that performs a custom iteration over an array or collection class by using the yield keyword. The yield return statement causes an element in the source sequence to be returned immediately to the caller before the next element in the source sequence is accessed. Although you write an iterator as a method, the compiler translates it into a nested class that is, in effect, a state machine. This class keeps track of the position of the iterator as long the foreach loop on the client code continues. Note: To see what the compiler does behind the scenes, use the ILDASM.exe tool to view the intermediate language (IL) code that is generated for an iterator method. An iterator is invoked from client code by using a foreach statement. For example, you can create an iterator for a class that returns the elements in reverse order, or that performs an operation on each element before the iterator returns it. When you create an iterator for your class or struct, you do not have to implement the whole IEnumerator interface. When the compiler detects your iterator, it will automatically generate the Current, MoveNext and Dispose methods of the IEnumerator or IEnumerator<(Of <(T>)>) interface. Iterators Overview An iterator is a section of code that returns an ordered sequence of values of the same type. An iterator can be used as the body of a method, an operator, or a get accessor. The iterator code uses the yield return statement to return each element in turn. yield break ends the iteration. Multiple iterators can be implemented on a class. Each iterator must have a unique name just like any class member, and can be invoked by client code in a foreach statement as follows: foreach(int x in SampleClass.Iterator2){}. The return type of an iterator must be IEnumerable, IEnumerator, IEnumerable<(Of <(T>)>), or IEnumerator<(Of <(T>)>). Iterators are the basis for the deferred execution behavior in LINQ queries. The yield keyword is used to specify the value, or values, that are returned. When the yield return statement is reached, the current location is stored. Execution is restarted from this location the next time that the iterator is called. Iterators are especially useful with collection classes, providing an easy way to iterate complex data structures such as binary trees. Example In this example, the DaysOfTheWeek class is a simple collection class that stores the days of the week as strings. After each iteration of a foreach loop, the next string in the collection is returned. C# public class DaysOfTheWeek : System.Collections.IEnumerable { string[] days = { "Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat" }; public System.Collections.IEnumerator GetEnumerator() { for (int i = 0; i < days.Length; i++) { yield return days[i]; } } } class TestDaysOfTheWeek { static void Main()

{

// Create an instance of the collection class DaysOfTheWeek week = new DaysOfTheWeek(); // Iterate with foreach foreach (string day in week) { System.Console.Write(day + " "); }

} } // Output: Sun Mon Tue Wed Thr Fri Sat

Using Iterators The most common way to create an iterator is to implement the GetEnumerator method on the IEnumerable interface, for example: C# public System.Collections.IEnumerator GetEnumerator() { for (int i = 0; i < 10; i++) { yield return i; } } The presence of the GetEnumerator method makes the type an enumerable type and allows using the foreach statement. If the method above was part of a class definition for ListClass, then it would be possible to use foreach on the class like this: C# static void Main() { ListClass listClass1 = new ListClass(); foreach (int i in listClass1) { System.Console.WriteLine(i); }

}

The foreach statement invokes ListClass.GetEnumerator() and uses the returned enumerator to iterate through the values. For an example of how to create a generic iterator that returns a IEnumerator<(Of <(T>)>) interface, see How to: Create an Iterator Block for a Generic List (C# Programming Guide). It is also possible to use named iterators to support different ways of iterating through the same collection of data. For example, you could provide one iterator which returns elements in ascending order, and one which returns elements in descending order. An iterator can also have parameters to enable clients to control all or part of the iteration behavior. The following iterator implements the IEnumerable interface using the named iterator SampleIterator: C# // Implementing the enumerable pattern public System.Collections.IEnumerable SampleIterator(int start, int end) { for (int i = start; i <= end; i++) { yield return i;

}

}

The named iterator is invoked like this: C# ListClass test = new ListClass(); foreach (int n in test.SampleIterator(1, 10)) { System.Console.WriteLine(n); } You can use more than one yield statement in the same iterator as in the following example: C# public System.Collections.IEnumerator GetEnumerator() { yield return "With an iterator, "; yield return "more than one "; yield return "value can be returned"; yield return "."; } You can then print the results using the following foreach statement: C# foreach (string element in new TestClass()) { System.Console.Write(element); } This example displays the following text: With an iterator, more than one value can be returned. On each successive iteration of the foreach loop (or the direct call to IEnumerator.MoveNext), the next iterator code body resumes after the previous yield statement and continues to the next until the end of the iterator body is reached, or a yield break statement is encountered. Iterators do not support the IEnumeratorReset()()() method. To re-iterate from the beginning, you must obtain a new iterator. Manage a group of associated data using collections Introduction Collections are an essential part of any modern programming language. Collection Classes have the following properties: Collection classes are defined as part of the System.Collections namespace. Most collection classes derive from the interfaces ICollection, IComparer, IEnumerable, IList, IDictionary, and IDictionaryEnumerator. Type Safety Most of the standard collections are not type safe. Therefore, all objects must be cast to their appropriate type when using them from with the collection. Also, in order to store value types, they must perform boxing/unboxing operations. Generics Because these collections are untyped, you should use generic collections unless backwards compatibility is needed.

Using generic collection classes provides increased type-safety and in some cases can provide better performance, especially when storing value types. Collection Classes The .NET Framework provides specialized classes for data storage and retrieval. These classes provide support for stacks, queues, lists, and hash tables. Most collection classes implement the same interfaces, and these interfaces may be inherited to create new collection classes that fit more specialized data storage needs. Note: Applications that target version 2.0 and later of the .NET Framework should use the generic collection classes in the System.Collections.Generic namespace, which provide more type-safety and efficiency than their nongeneric counterparts. C# ArrayList list = new ArrayList(); list.Add(10); list.Add(20); Collection Classes Overview Collection Classes have the following properties Collection classes are defined as part of the System.Collections or System.Collections.Generic namespace. Most collection classes derive from the interfaces ICollection, IComparer, IEnumerable, IList, IDictionary, and IDictionaryEnumerator and their generic equivalents. Generic collection classes provide increased type-safety and in some cases can provide better performance, especially when they store value types. For more information, see Benefits of Generics (C# Programming Guide). Collections and Data Structures Closely related data can be handled more efficiently when grouped together into a collection. Instead of writing separate code to handle each individual object, you can use the same code to process all the elements of a collection. To manage a collection, use the Array class and the System.Collections classes to add, remove, and modify either individual elements of the collection or a range of elements. An entire collection can even be copied to another collection. Some Collections classes have sorting capabilities, and most are indexed. Memory management is handled automatically, and the capacity of a collection is expanded as required. Synchronization provides thread safety when accessing members of the collection. Some Collections classes can generate wrappers that make the collection read-only or fixed-size. Any Collections class can generate its own enumerator that makes it easy to iterate through the elements. In the .NET Framework version 2.0, generic collection classes provide new functionality and make it easy to create strongly typed collections. See the System.Collections.Generic and System.Collections.ObjectModel namespaces. The LINQ to Objects feature allows you to use LINQ queries to access in-memory objects as long as the object type implements IEnumerable or IEnumerable<(Of <(T>)>). LINQ queries provide a common pattern for accessing data; are typically more concise and readable than standard foreach loops; and provide filtering, ordering and grouping capabilities. LINQ queries can also improve performance. For more information, see LINQ to Objects. Commonly Used Collection Types Collection types are the common variations of data collections, such as hash tables, queues, stacks, dictionaries, and lists. Collections are based on the ICollection interface, the IList interface, the IDictionary interface, or their generic counterparts. The IList interface and the IDictionary interface are both derived from the ICollection interface; therefore, all collections are based on the ICollection interface either directly or indirectly. In collections based on the IList interface (such as Array, ArrayList, or List<(Of <(T>)>)) or directly on the ICollection interface (such as Queue, Stack, or LinkedList<(Of <(T>)>)), every element contains only a value. In collections based on the IDictionary interface (such as the Hashtable and SortedList classes, or the Dictionary<(Of <(TKey,

TValue>)>) and SortedList<(Of <(TKey, TValue>)>) generic classes), every element contains both a key and a value. The KeyedCollection<(Of <(TKey, TItem>)>) class is unique because it is a list of values with keys embedded within the values and, therefore, it behaves like a list and like a dictionary. Generic collections are the best solution to strong typing. However, if your language does not support generics, the System.Collections namespace includes base collections, such as CollectionBase, ReadOnlyCollectionBase, and DictionaryBase, which are abstract base classes that can be extended to create collection classes that are strongly typed. Collections can vary, depending on how the elements are stored, how they are sorted, how searches are performed, and how comparisons are made. The Queue class and the Queue<(Of <(T>)>) generic class provide first-in-first-out lists, while the Stack class and the Stack<(Of <(T>)>) generic class provide last-infirst-out lists. The SortedList class and the SortedList<(Of <(TKey, TValue>)>) generic class provide sorted versions of the Hashtable class and the Dictionary<(Of <(TKey, TValue>)>) generic class. The elements of a Hashtable or a Dictionary<(Of <(TKey, TValue>)>) are accessible only by the key of the element, but the elements of a SortedList or a KeyedCollection<(Of <(TKey, TItem>)>) are accessible either by the key or by the index of the element. The indexes in all collections are zero-based, except Array, which allows arrays that are not zero-based. The LINQ to Objects feature allows you to use LINQ queries to access in-memory objects as long as the object type implements IEnumerable or IEnumerable<(Of <(T>)>). LINQ queries provide a common pattern for accessing data; are typically more concise and readable than standard foreach loops; and provide filtering, ordering and grouping capabilities. LINQ queries can also improve performance. For more information, see LINQ to Objects. Manage data in a .NET Framework application Fundamental types The following table lists the fundamental types of the .NET Framework which are found in the System namespace: Fundamental types Namespace Description System.Object Supports all classes in the .NET Framework class hierarchy and provides low-level services to derived classes. This is the ultimate base class of all classes in the .NET Framework: it is the root of the type hierarchy. System.ValueType Provides the base class for all value types. System.Nullable Supports a value type that can be assigned a null reference (like a reference type). Cannot be inherited. System.String A built-in reference type. System.Array All arrays—even if their elements are value types. System.Attribute A method of associating declarative information with C# code—methods, properties, types, etc. Once associated with a program entity, the attribute can be queried at run time using a technique called reflection. System.Exception Provides the base class for all exceptions. System.Runtime. CompilerServices. TypeForwardedTo Attribute Specifies a destination type in another assembly. Data types C# supports two categories of data types: value types and reference types. The main difference between these two types is how their values are stored in memory. Value types Value types have their value stored on the stack—like variables in C++—unless they are embedded within a reference type. Value types include all of the standard predefined integral data types as well as structures and enumerations. All of the simple types—those integral to the C# language—are aliases of the .NET Framework System types. The Stack

The stack is a section of memory that exists for the currently executing part of the program, and typically holds reserved space for local variables. Memory reserved in the program stack, for a particular method, is reclaimed and subsequently reused automatically when the method returns. For Example: If method A calls method B before returning, method A's stack memory will persist all the way through until method A finishes, including the portion of the time that method B is being executed. Reference types Reference types sit on the stack, but they hold the address of an object on the heap, much like pointers in C+ +. Reference types include objects and strings. Reference types store the address of their data, also known as pointers, on the stack. The actual data that address refers to is stored in an area of memory called the heap. The Heap The heap is a section of reserved memory that might persist past the current method, thread, or, possibly, the entire lifetime of the program. The runtime environment manages the memory used by the heap through a process called garbage collection. Periodically, garbage collection recovers memory as needed by disposing of items that are no longer referenced. Nested Classes A nested class is one that is created inside another class. Why ? A good question that is not always immediately answerable. There are several reasons to have inner classes. But the two that jump to mind are these: Organizing code into real world situations where there is a special relationship between two objects. Hiding a class within another class so that you do not want the inner class to be used from outside of the class it is created within. Polymorphism Suppose you want to model a car. Some objects only make sense within a whole car and not on their own. We can say that the car is composed of other objects. Polymorphism uses two terms to describe this, aggregation and composition. These relationships form a whole-part relationship that you can use to decompose objects into more manageable entities. Any object that can exist and be used independently of the relationship uses aggregation. Any object that has no meaning outside of the relationship uses composition. An example For example, a class named Car would have an engine. Objects that fall into this relationship use of the term "is a part of". "An engine is a part of a car". In UML, an object relationship that is formed by aggregation is drawn using an empty diamond. An object relationship that is formed using composition is drawn using a filled diamond. The following UML diagram illustrates the concepts of aggregation and composition.

In the diagram above, the battery and the engine have no meaning outside of the car, as the car cannot work without either of them, so the relationship is formed using composition. However, a car can work without doors, so the relationship is formed using aggregation. From the previous diagram, we can create a possible small code sample that shows the two forms of relationship. Objects that use composition are created as inner classes. namespace MyCars { public class Car { // Aggregation uses instances of objects created outside of // this class protected Door FrontRight; protected Door FrontLeft; protected Door RearRight; protected Door RearLeft; // inner classes used to create objects that are intrinsically // linked to the class Car protected class Engine { public int horsePower; } protected class Battery { public int voltage; } // Composition uses instances of objects that are created as // part of this object protected Engine theEngine; protected Battery theBattery; public Car() { theEngine = new Engine(); theBattery = new Battery(); }

}

public class Door { public int position; } }By giving each of the members protected access modifiers, each class that inherits from the class Car has access to each of the members of the class Car. namespace MyCars { // Inherit from class Car public class FordCapri : Car { public FordCapri() { theEngine.horsePower = 2000; }

} } Declaration and use A nested class is declared in the same manner as a normal class declaration. The difference is that a nested class has access to all of the available modifiers. The this keyword reference in the inner class only holds a reference to the inner class. Data members of the outer class are not accessible using the this reference in the inner class. If this is needed, pass a reference of the outer class into the constructor of the inner class. static members of the outer class are available in the inner class irrespective of the accessibility level. Nullable type The Basics Nullable types are instances of the System.Nullable struct. They can represent all the values of an underlying type plus an additional null value. The reason for using nullable types is to overcome the issue of not being able to easily determine if a value type is empty or undefined. Unlike reference types - which can be assigned a null value - null is not assignable to primitive value types. Use nullable types as a consistent solution for determining whether a value type is either empty or undefined. Declaration You can declare nullable types in one of two ways: System.Nullable<T> variableName; // method 1

T? variableName; // method 2 Where T is the underlying type of the nullable type. T can be any value type including struct. For example: Nullable<int> i = null; int? j = 10; double? d1 = 3.14; bool? flag = null; char? letter = 'a'; int?[] arr = new int?[10]; Properties Each instance of a nullable type has two public read-only properties: HasValue - Type is bool. True if the variable contains a non-null value. For example: int? x = 10; if (x.HasValue) { System.Console.WriteLine (x.Value); } else { System.Console.WriteLine ("Undefined"); }Value - Type is the underlying type. If HasValue is true, then Value contains a meaningful value. If HasValue is false, accessing Value will throw an InvalidOperationException. Useful methods GetType - Gets the Type of the underlying value type. GetValueOrDefault() - Retrieves the value of the current Nullable object, or the object's default value. GetValueOrDefault(T defaultValue) - Retrieves the value of the current Nullable object, or the specified defaultValue if the value of the object is null. For example: float? mySingle = null; float? yourSingle = -1.0f; yourSingle = mySingle.GetValueOrDefault(-333.33f); // yourSingle now equals -333.33f

Boxing and Unboxing When a nullable type is boxed (cast to a reference type), only the value of the nullable type is boxed. So if HasValue is true, the value of Value is boxed. If HasValue is false, a null reference is boxed. When the resulting object is unboxed, a new nullable type is created, and HasValue and Value are populated appropriately. To convert a nullable type back to the primitive type on which it is based, you can use the function System.Nullable.GetValueOrDefault(). int? NullableNumber = null; int Number = NullableNumber.GetValueOrDefault(); // Default value is 0 NullableNumber = 146; Number = NullableNumber.GetValueOrDefault(); // Value is 146 However, if you want to specify your own default value, you can either specify a default value or use the ?? operator. The ?? operator will return the value if it is not null or the given value on the right side of the ??. int? NullableNumber = null; int Number = NullableNumber.GetValueOrDefault(-1); // Number is -1 NullableNumber = 146; Number = NullableNumber.GetValueOrDefault(-1); // Number is 146 // Is the same as int? NullableNumber = null; int Number = NullableNumber ?? -1; // Number is -1 NullableNumber = 146; Number = NullableNumber ?? -1; // Number is 146 Boxing Nullable Types Objects based on nullable types are only boxed if the object is non-null. If HasValue is false, the object reference is assigned to null instead of boxing. For example: bool? b = null; object o = b; // Now o is null. If the object is non-null -- if HasValue is true -- then boxing occurs, but only the underlying type that the nullable object is based on is boxed. Boxing a non-null nullable value type boxes the value type itself, not the System..::.Nullable<(Of <(T>)>) that wraps the value type. For example: bool? b = false; int? i = 44; object bBoxed = b; // bBoxed contains a boxed bool. object iBoxed = i; // iBoxed contains a boxed int. The two boxed objects are identical to those created by boxing non-nullable types. And, just like non-nullable boxed types, they can be unboxed into nullable types, as in the following example: bool? b2 = (bool?)bBoxed; int? i2 = (int?)iBoxed; Remarks The behavior of nullable types when boxed provides two advantages: Nullable objects and their boxed counterpart can be tested for null: bool? b = null; object boxedB = b; if (b == null) {

// True. } if (boxedB == null) { // Also true. } Boxed nullable types fully support the functionality of the underlying type: double? d = 44.4; object iBoxed = d; // Access IConvertible interface implemented by double. IConvertible ic = (IConvertible)iBoxed; int i = ic.ToInt32(null); string str = ic.ToString(); How to: Identify a Nullable Type You can use the C# typeof operator to create a Type object that represents a Nullable type: System.Type type = typeof(int?); You can also use the classes and methods of the System.Reflection namespace to generate Type objects that represent Nullable types. However, if you try to obtain type information from Nullable variables at runtime by using the GetType method or the is operator, the result is a Type object that represents the underlying type, not the Nullable type itself. Calling GetType on a Nullable type causes a boxing operation to be performed when the type is implicitly converted to Object. Therefore GetType always returns a Type object that represents the underlying type, not the Nullable type. int? i = 5; Type t = i.GetType(); Console.WriteLine(t.FullName); //"System.Int32" The C# is operator also operates on a Nullable's underlying type. Therefore you cannot use is to determine whether a variable is a Nullable type. The following example shows that the is operator treats a Nullable<int> variable as an int. static void Main(string[] args) { int? i = 5; if (i is int) // true //… } Example Use the following code to determine whether a Type object represents a Nullable type. Remember that this code always returns false if the Type object was returned from a call to GetType, as explained earlier in this topic. if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) {…} Nullable(T) Members Represents an object whose underlying type is a value type that can also be assigned nullNothingnullptra null reference (Nothing in Visual Basic) like a reference type. The Nullable(T) type exposes the following members. Constructors Name Nullable(T) Description Initializes a new instance of the Nullable(T) structure to the specified value.

Methods Name Equals

Description Indicates whether the current Nullable(T) object is equal to a specified object. (Overrides ValueType..::.Equals(Object).) Finalize Allows an Object to attempt to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. (Inherited from Object.) GetHashCode Retrieves the hash code of the object returned by the Value property. (Overrides ValueType..::.GetHashCode()()().) GetType Gets the Type of the current instance. (Inherited from Object.) GetValueOrDefault Overloaded. Retrieves the value of the current Nullable(T) object, or a default value. MemberwiseClone Creates a shallow copy of the current Object. (Inherited from Object.) ToString Returns the text representation of the value of the current Nullable(T) object. (Overrides ValueType..::.ToString()()().) Operators Name Explicit Implicit Properties Name HasValue Value Description Returns the value of a specified Nullable (T) value. Creates a new Nullable (T) object initialized to a specified value. Description Gets a value indicating whether the current Nullable (T) object has a value. Gets the value of the current Nullable(T) value.

Using Nullable Types Nullable types can represent all the values of an underlying type, and an additional null value. Nullable types are declared in one of two ways: System.Nullable<T> variable -orT? variable T is the underlying type of the nullable type. T can be any value type including struct; it cannot be a reference type. For an example of when you might use a nullable type, consider how an ordinary Boolean variable can have two values: true and false. There is no value that signifies "undefined". In many programming applications, most notably database interactions, variables can occur in an undefined state. For example, a field in a database may contain the values true or false, but it may also contain no value at all. Similarly, reference types can be set to null to indicate that they are not initialized. This disparity can create extra programming work, with additional variables used to store state information, the use of special values, and so on. The nullable type modifier enables C# to create value-type variables that indicate an undefined value. Examples of Nullable Types Any value type may be used as the basis for a nullable type. For example: C# int? i = 10; double? d1 = 3.14; bool? flag = null; char? letter = 'a'; int?[] arr = new int?[10]; The Members of Nullable Types Each instance of a nullable type has two public read-only properties:

HasValue HasValue is of type bool. It is set to true when the variable contains a non-null value. Value Value is of the same type as the underlying type. If HasValue is true, Value contains a meaningful value. If HasValue is false, accessing Value will throw a InvalidOperationException. In this example, the HasValue member is used to test whether the variable contains a value before it tries to display it. C# int? x = 10; if (x.HasValue) { System.Console.WriteLine(x.Value); } else { System.Console.WriteLine("Undefined"); } Testing for a value can also be done as in the following example: C# int? y = 10; if (y != null) { System.Console.WriteLine(y.Value); } else { System.Console.WriteLine("Undefined"); } Explicit Conversions A nullable type can be cast to a regular type, either explicitly with a cast, or by using the Value property. For example: C# int? n = null; //int m1 = n; // Will not compile. int m2 = (int)n; // Compiles, but will create an exception if x is null. int m3 = n.Value; // Compiles, but will create an exception if x is null. If a user-defined conversion is defined between two data types, the same conversion can also be used with the nullable versions of these data types. Implicit Conversions A variable of nullable type can be set to null with the null keyword, as shown in the following example: C# int? n1 = null; The conversion from an ordinary type to a nullable type, is implicit.

C# int? n2; n2 = 10; // Implicit conversion. Operators The predefined unary and binary operators and any user-defined operators that exist for value types may also be used by nullable types. These operators produce a null value if the operands are null; otherwise, the operator uses the contained value to calculate the result. For example: C# int? a = 10; int? b = null; a++; // Increment by 1, now a is 11. a = a * 10; // Multiply by 10, now a is 110. a = a + b; // Add b, now a is null. When performing comparisons with nullable types, if one of the nullable types is null, the comparison is always evaluated to be false. It is therefore important not to assume that because a comparison is false, the opposite case is true. For example: C# int? num1 = 10; int? num2 = null; if (num1 >= num2) { System.Console.WriteLine("num1 is greater than or equal to num2"); } else { // num1 is NOT less than num2 } The conclusion in the else statement is not valid because num2 is null and therefore does not contain a value. A comparison of two nullable types which are both null will be evaluated to true. The ?? Operator The ?? operator defines a default value that is returned when a nullable type is assigned to a non-nullable type. C# int? c = null; // d = c, unless c is null, in which case d = -1. int d = c ?? -1; This operator can also be used with multiple nullable types. For example: C# int? e = null; int? f = null; // g = e or f, unless e and f are both null, in which case g = -1. int g = e ?? f ?? -1; The bool? type The bool? nullable type can contain three different values: true, false and null. For information about how to cast from a bool? to a bool, see How to: Safely Cast from bool? to bool (C# Programming Guide).

Nullable Booleans are like the Boolean variable type that is used in SQL. To ensure that the results produced by the & and | operators are consistent with the three-valued Boolean type in SQL, the following predefined operators are provided: bool? operator &(bool? x, bool? y) bool? operator |(bool? x, bool? y) The results of these operators are listed in the following table: X true true true false false false null null null y true false null true false null true false null x&y true false null false false false null false null x|y true true true true false null true null null

?? Operator The ?? operator is called the null-coalescing operator and is used to define a default value for a nullable value types as well as reference types. It returns the left-hand operand if it is not null; otherwise it returns the right operand. Remarks A nullable type can contain a value, or it can be undefined. The ?? operator defines the default value to be returned when a nullable type is assigned to a non-nullable type. If you try to assign a nullable value type to a non-nullable value type without using the ?? operator, you will generate a compile-time error. If you use a cast, and the nullable value type is currently undefined, an InvalidOperationException exception will be thrown. For more information, see Nullable Types (C# Programming Guide). The result of a ?? operator is not considered to be a constant even if both its arguments are constants. Example C# class NullCoalesce { static int? GetNullableInt() { return null; } static string GetStringValue() { return null; }

static void Main() { // ?? operator example. int? x = null; // y = x, unless x is null, in which case y = -1. int y = x ?? -1; // Assign i to return value of method, unless // return value is null, in which case assign // default value of int to i. int i = GetNullableInt() ?? default(int); string s = GetStringValue(); // ?? also works with reference types. // Display contents of s, unless s is null, // in which case display "Unspecified". Console.WriteLine(s ?? "Unspecified");

} }

Queue class What Is the Queue Class? The Queue class represents a way of managing elements in a collection using the First In First Out (FIFO) technique for adding and removing elements. FIFO simply means that whichever element was added to the collection first will automatically be the one removed first. FIFO In the Queue Class Elements are added to the end of the collection and removed from the beginning. In this way the element that was added first will be the one removed or retrieved first. Members This class has several methods and properties associated with it. Below is a non-exhaustive list of its most important methods and properties. Count - Public property that gets the number of elements in the Queue Clear() - Method that removes all objects from the Queue Contains() - Method that determines if an element is in the Queue CopyTo() - Method that copies the Queue elements to an existing one-dimensional array Dequeue() - Method that removes and returns the object at the beginning of the Queue Enqueue() - Method that adds an object to the end of the Queue GetEnumerator() - Method that returns an enumerator for the Queue Peek() - Method that returns the object at the beginning of the Queue without removing it ToArray() - Method that copies the elements to a new array Adding and Removing Elements Add elements to a queue using the Enqueue() method. Remove elements from a queue by using the Dequeue() method. Code Examples Create and Populate a Queue // Create a queue Queue multiplesOfFive = new Queue(); // populate the array with the first 10 multiples of 5 for (int i = 0 ; i < 10 ; i++) {

multiplesOfFive.Enqueue( i * 5 ); }Remove Elements From the Queue // Create the queue Queue primes = new Queue(); primes.Enqueue( primes.Enqueue( primes.Enqueue( primes.Enqueue( 2 3 5 7 ); ); ); );

// Dequeue will return the first item that was added and remove it // firstPrime will be 2 int firstPrime = (int) primes.Dequeue(); // secondPrime will be 3 int secondPrime = (int) primes.Dequeue();[edit]View First Element Without Removing It // Create the queue Queue messages = new Queue(); messages.Enqueue( messages.Enqueue( messages.Enqueue( messages.Enqueue( "Joe:Hey Joe..." ); "Bob:I'll see you tommorrow" ); "Jane:Yesterday, I was gone..." ); "Karen:How are you?" );

// Peek will allow a the first item to be read without removing it string firstMessage = (string) messages.Peek(); if( firstMessage.StartsWith( "Bob" ) ){ messages.Dequeue(); // Display message // ... } Queue Class Represents a first-in, first-out collection of objects. Namespace: System.Collections Assembly: mscorlib (in mscorlib.dll) Syntax Visual Basic (Declaration) <SerializableAttribute> _ <ComVisibleAttribute(True)> _ Public Class Queue _ Implements ICollection, IEnumerable, ICloneable Visual Basic (Usage) Dim instance As Queue C# [SerializableAttribute] [ComVisibleAttribute(true)] public class Queue : ICollection, IEnumerable, ICloneable Remarks

Queues are useful for storing messages in the order they were received for sequential processing. This class implements a queue as a circular array. Objects stored in a Queue are inserted at one end and removed from the other. The capacity of a Queue is the number of elements the Queue can hold. As elements are added to a Queue, the capacity is automatically increased as required through reallocation. The capacity can be decreased by calling TrimToSize. The growth factor is the number by which the current capacity is multiplied when a greater capacity is required. The growth factor is determined when the Queue is constructed. The default growth factor is 2.0. The capacity of the Queue will always increase by at least a minimum of four, regardless of the growth factor. For example, a Queue with a growth factor of 1.0 will always increase in capacity by four when a greater capacity is required. Queue accepts nullNothingnullptra null reference (Nothing in Visual Basic) as a valid value and allows duplicate elements. For the generic version of this collection, see System.Collections.Generic..::.Queue<(Of <(T>)>) Examples The following example shows how to create and add values to a Queue and how to print out its values. Visual Basic Imports System Imports System.Collections Public Class SamplesQueue Public Shared Sub Main() ' Creates and initializes a new Queue. Dim myQ As New Queue() myQ.Enqueue("Hello") myQ.Enqueue("World") myQ.Enqueue("!") ' Displays the properties and values of the Queue. Console.WriteLine("myQ") Console.WriteLine(" Count: {0}", myQ.Count) Console.Write(" Values:") PrintValues(myQ) End Sub 'Main Public Shared Sub PrintValues(myCollection As IEnumerable) Dim obj As [Object] For Each obj In myCollection Console.Write(" {0}", obj) Next obj Console.WriteLine() End Sub 'PrintValues End Class 'SamplesQueue ' This code produces the following output. ' ' myQ ' Count: 3 ' Values: Hello World ! C#

using System; using System.Collections; public class SamplesQueue { public static void Main() { // Creates and initializes a new Queue. Queue myQ = new Queue(); myQ.Enqueue("Hello"); myQ.Enqueue("World"); myQ.Enqueue("!"); // Displays the properties and values of the Queue. Console.WriteLine( "myQ" ); Console.WriteLine( "\tCount: {0}", myQ.Count ); Console.Write( "\tValues:" ); PrintValues( myQ );

}

} /* This code produces the following output. myQ Count: Values: */ 3 Hello

public static void PrintValues( IEnumerable myCollection ) { foreach ( Object obj in myCollection ) Console.Write( " {0}", obj ); Console.WriteLine(); }

World

!

Inheritance Hierarchy System..::.Object System.Collections..::.Queue Thread Safety Public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe. To guarantee the thread safety of the Queue, all operations must be done through the wrapper returned by the Synchronized method. Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads can still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or catch the exceptions resulting from changes made by other threads. Reference types The Basics Reference types are more commonly referred to as objects. They include instances Classes, Interfaces, Delegates and arrays, as well as the built-in reference types System.Object and System.String. Variables of type reference do not hold the actual data for the object (like value types); instead they hold a reference to the data. The data is allocated on the heap and is automatically garbage collected when it is no longer in use. The object type is an alias for Object in the .NET Framework. In the unified type system of C#, all types, predefined and user-defined, reference types and value types, inherit directly or indirectly from Object. You can assign values of any type to variables of type object. When a variable of a value type is converted to object, it

is said to be boxed. When a variable of type object is converted to a value type, it is said to be unboxed. For more information, see Boxing and Unboxing. Copying reference types Assigning a variable of type reference to another variable of type reference copies that reference (it tells the new object where the place in memory is), but does not make a copy of the object. In order to copy the values held by a reference type, a deep copy is required. That is to say, each item in the reference type must be manually copied. This can be accomplished in several ways, with some of the system types providing easy methods. Passing references Unlike value types, there is no need to use the ref keyword when passing reference types. This can be shown in a simple example. class Program { static void Main(string[] args) { Program prog = new Program(); SimpleObject ob = new SimpleObject(); Console.WriteLine("The value of X is " + ob.X.ToString()); prog.PassRef(ob); Console.WriteLine("The value of X is " + ob.X.ToString()); } public void PassRef(SimpleObject ob) { ob.X = 7; } } public class SimpleObject { public SimpleObject() { } public int X = 2; }The resultant output is: The value of X is 2 The value of X is 7 Passing parameters using ref When you pass a reference using the ref keyword, the method expects a pointer to the pointer of an object on the heap. If you don't use the ref keyword, the method expects a pointer of an object on the heap. Passing parameters using out Using the out keyword works in the same manner as using the ref keyword, but the argument passed to an out parameter does not have to be initialized first. Using the reference types Declaring Classes Nested Classes Class Members Constructors and Destructors

Copy Constructors Fields and Properties Interfaces and Abstract Classes const, static and readonly Reference Types Variables of reference types, referred to as objects, store references to the actual data. This section introduces the following keywords used to declare reference types: class interface delegate This section also introduces the following built-in reference types: object string SortedList class Description The SortedList class represents a collection of key-and-value pairs that are sorted by the keys and are accessible by key and by index. A SortedList is a hybrid between a Hashtable and an Array. When an element is accessed by its key using the Item indexer property, it behaves like a Hashtable. When an element is accessed by its index using GetByIndex or SetByIndex, it behaves like an Array. Members Here are some of the common members of the SortedList class. For a complete listing see the MSDN Reference at the bottom of the page. Properties Capacity - Gets or sets the capacity of a SortedList object. Count - Gets the number of elements contained in a SortedList object. IsFixedSize - Gets a value indicating whether a SortedList object has a fixed size. A collection with a fixed size does not allow the addition or removal of elements after the collection is created, but does allow the modification of existing elements. Item - Gets and sets the value associated with a specific key in a SortedList object. Keys - Gets the keys in a SortedList object. Values - Gets the values in a SortedList object. Methods Add(key,value) - Adds an element with the specified key and value to a SortedList object. The value can be a null reference. If Count already equals Capacity, the capacity of the SortedList object is increased by automatically reallocating the internal array, and the existing elements are copied to the new array before the new element is added. You can also use the Item property to add new elements by setting the value of a key that does not exist in the SortedList object (for example, myCollection["myNonexistentKey"] = myValue). However, if the specified key already exists in the SortedList, setting the Item property overwrites the old value. In contrast, the Add method does not modify existing elements. Characteristics Of A SortedList A SortedList internally maintains two arrays to store the elements of the list; that is, one array for the keys and another array for the associated values. Each element is a key-and-value pair that can be accessed as a DictionaryEntry object. A key cannot be a null reference, but a value can be. The Sorting Of Elements

The capacity of a SortedList is the number of elements that the list can hold. As elements are added to a SortedList, the capacity is automatically increased as required through reallocation. The capacity can be decreased by calling TrimToSize or by setting the Capacity property explicitly. The elements of a SortedList are sorted by the keys either according to a specific IComparer implementation specified when the SortedList is created or according to the IComparable implementation provided by the keys themselves. In either case, a SortedList does not allow duplicate keys. The Sorting Of Indexes The index sequence is based on the sort sequence. When an element is added, it is inserted into SortedList in the correct sort order, and the indexing adjusts accordingly. When an element is removed, the indexing also adjusts accordingly. Therefore, the index of a specific key-and-value pair might change as elements are added or removed from the SortedList. Code Examples Adding Items To A Sorted List mySortedList.Add( "First", "Hello" ); mySortedList.Add( "Second", "World" ); mySortedList.Add( "Third", "!" ); SortedList Class Represents a collection of key/value pairs that are sorted by the keys and are accessible by key and by index. Namespace: System.Collections Assembly: mscorlib (in mscorlib.dll) Syntax Visual Basic (Declaration) <SerializableAttribute> _ <ComVisibleAttribute(True)> _ Public Class SortedList _ Implements IDictionary, ICollection, IEnumerable, ICloneable Visual Basic (Usage) Dim instance As SortedList C# [SerializableAttribute] [ComVisibleAttribute(true)] public class SortedList : IDictionary, ICollection, IEnumerable, ICloneable Remarks For the generic version of this collection, see System.Collections.Generic..::.SortedList<(Of <(TKey, TValue>)>). A SortedList element can be accessed by its key, like an element in any IDictionary implementation, or by its index, like an element in any IList implementation. A SortedList object internally maintains two arrays to store the elements of the list; that is, one array for the keys and another array for the associated values. Each element is a key/value pair that can be accessed as a DictionaryEntry object. A key cannot be nullNothingnullptra null reference (Nothing in Visual Basic), but a value can be. The capacity of a SortedList object is the number of elements the SortedList can hold. As elements are added to a SortedList, the capacity is automatically increased as required through reallocation. The capacity can be decreased by calling TrimToSize or by setting the Capacity property explicitly. The elements of a SortedList object are sorted by the keys either according to a specific IComparer implementation specified when the SortedList is created or according to the IComparable implementation provided by the keys themselves. In either case, a SortedList does not allow duplicate keys. The index sequence is based on the sort sequence. When an element is added, it is inserted into SortedList in the correct sort order, and the indexing adjusts accordingly. When an element is removed, the indexing also adjusts accordingly. Therefore, the index of a specific key/value pair might change as elements are added or removed from the SortedList object.

Operations on a SortedList object tend to be slower than operations on a Hashtable object because of the sorting. However, the SortedList offers more flexibility by allowing access to the values either through the associated keys or through the indexes. Elements in this collection can be accessed using an integer index. Indexes in this collection are zero-based. The foreach statement of the C# language (for each in Visual Basic) requires the type of each element in the collection. Since each element of the SortedList object is a key/value pair, the element type is not the type of the key or the type of the value. Rather, the element type is DictionaryEntry. For example: C# foreach (DictionaryEntry de in mySortedList) {...} Visual Basic Copy Code For Each de As DictionaryEntry In mySortedList ... Next myDE The foreach statement is a wrapper around the enumerator, which allows only reading from, not writing to, the collection. Examples The following code example shows how to create and initialize a SortedList object and how to print out its keys and values. Visual Basic Imports System Imports System.Collections Imports Microsoft.VisualBasic Public Class SamplesSortedList Public Shared Sub Main() ' Creates and initializes a new SortedList. Dim mySL As New SortedList() mySL.Add("First", "Hello") mySL.Add("Second", "World") mySL.Add("Third", "!") ' Displays the properties and values of the SortedList. Console.WriteLine("mySL") Console.WriteLine(" Count: {0}", mySL.Count) Console.WriteLine(" Capacity: {0}", mySL.Capacity) Console.WriteLine(" Keys and Values:") PrintKeysAndValues(mySL) End Sub Public Shared Sub PrintKeysAndValues(myList As SortedList) Console.WriteLine(ControlChars.Tab & "-KEY-" & ControlChars.Tab & _ "-VALUE-") Dim i As Integer For i = 0 To myList.Count - 1 Console.WriteLine(ControlChars.Tab & "{0}:" & ControlChars.Tab & _ "{1}", myList.GetKey(i), myList.GetByIndex(i)) Next i Console.WriteLine() End Sub End Class

' This code produces the following output. ' ' mySL ' Count: 3 ' Capacity: 16 ' Keys and Values: ' -KEY-VALUE' First: Hello ' Second: World ' Third: ! C# using System; using System.Collections; public class SamplesSortedList { public static void Main() { // Creates and initializes a new SortedList. SortedList mySL = new SortedList(); mySL.Add("First", "Hello"); mySL.Add("Second", "World"); mySL.Add("Third", "!"); // Displays the properties and values of the SortedList. Console.WriteLine( "mySL" ); Console.WriteLine( " Count: {0}", mySL.Count ); Console.WriteLine( " Capacity: {0}", mySL.Capacity ); Console.WriteLine( " Keys and Values:" ); PrintKeysAndValues( mySL ); } public static void PrintKeysAndValues( SortedList myList ) { Console.WriteLine( "\t-KEY-\t-VALUE-" ); for ( int i = 0; i < myList.Count; i++ ) { Console.WriteLine( "\t{0}:\t{1}", myList.GetKey(i), myList.GetByIndex(i) ); } Console.WriteLine(); } } /* This code produces the following output. mySL Count: 3 Capacity: 16 Keys and Values: -KEY- -VALUEFirst: Hello Second: World Third: ! */ Inheritance Hierarchy System..::.Object System.Collections..::.SortedList

Thread Safety Public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe. A SortedList object can support multiple readers concurrently, as long as the collection is not modified. To guarantee the thread safety of the SortedList, all operations must be done through the wrapper returned by the Synchronized method. Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads can still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or catch the exceptions resulting from changes made by other threads. SortedList Members Represents a collection of key/value pairs that are sorted by the keys and are accessible by key and by index. The SortedList type exposes the following members. Constructors Name SortedList Overloaded. MethodsName Add Clear Clone Contains ContainsKey ContainsValue CopyTo Equals Finalize GetByIndex GetEnumerator GetHashCode GetKey GetKeyList GetType GetValueList IndexOfKey IndexOfValue MemberwiseClone Remove RemoveAt SetByIndex Synchronized ToString TrimToSize Extension Methods Name AsQueryable Cast Enumerable.) OfType Enumerable.) Description Initializes a new instance of the SortedList class.

Description Adds an element with the specified key and value to a SortedList object. Removes all elements from a SortedList object. Creates a shallow copy of a SortedList object. Determines whether a SortedList object contains a specific key. Determines whether a SortedList object contains a specific key. Determines whether a SortedList object contains a specific value. Copies SortedList elements to a one-dimensional Array object, starting at the specified index in the array. Determines whether the specified Object is equal to the current Object. (Inherited from Object.) Allows an Object to attempt to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. (Inherited from Object.) Gets the value at the specified index of a SortedList object. Returns an IDictionaryEnumerator object that iterates through a SortedList object. Serves as a hash function for a particular type. (Inherited from Object.) Gets the key at the specified index of a SortedList object. Gets the keys in a SortedList object. Gets the Type of the current instance. (Inherited from Object.) Gets the values in a SortedList object. Returns the zero-based index of the specified key in a SortedList object. Returns the zero-based index of the first occurrence of the specified value in a SortedList object. Creates a shallow copy of the current Object. (Inherited from Object.) Removes the element with the specified key from a SortedList object. Removes the element at the specified index of a SortedList object. Replaces the value at a specific index in a SortedList object. Returns a synchronized (thread-safe) wrapper for a SortedList object. Returns a String that represents the current Object. (Inherited from Object.) Sets the capacity to the actual number of elements in a SortedList object. Description Converts an IEnumerable to an IQueryable. (Defined by Queryable.) Converts the elements of an IEnumerable to the specified type. (Defined by Filters the elements of an IEnumerable based on a specified type. (Defined by

Properties Name Capacity Count IsFixedSize IsReadOnly IsSynchronized Item Keys SyncRoot Values

Description Gets or sets the capacity of a SortedList object. Gets the number of elements contained in a SortedList object. Gets a value indicating whether a SortedList object has a fixed size. Gets a value indicating whether a SortedList object is read-only. Gets a value indicating whether access to a SortedList object is synchronized (thread safe). Gets and sets the value associated with a specific key in a SortedList object. Gets the keys in a SortedList object. Gets an object that can be used to synchronize access to a SortedList object. Gets the values in a SortedList object.

Explicit Interface Implementations Name Description IEnumerable..::.GetEnumerator Returns an IEnumerator that iterates through the SortedList. Stack class Description The Stack class represents a way of managing elements in a collection using the Last In First Out (LIFO) technique for adding and removing elements. LIFO simply means that the last element added to a collection will automatially be the first one removed. LIFO In a Stack In the Stack class elements are added to the end of a collection and removed from the end as well. In this way the last element added to the stack will also be the first one removed or retrieved. Members Here are some of the common members of the Stack class. For a complete listing see the MSDN Reference at the bottom of the page. Properties Count - Gets the number of elements contained in the Stack. Methods Push(element) - Adds a new object to the last position of the Stack. Pop() - Returns and removes the last object of the Stack. Peek() - Returns the object at the top of the Stack without removing it. IsEmpty() - Validates if the Stack is empty. Adding and Removing Elements Add elements to the stack using the Push() method. Remove elements from the stack using the Pop() method. Code Examples Create and Populate a Stack // Create stack Stack nouns = new Stack(); // Populate stack nouns.Push(cat); nouns.Push(dog); nouns.Push(chair); nouns.Push(Mary); nouns.Push(sheqhita); nouns.Push(home); nouns.Push(school);Remove Elements from a Stack //create stack

Stack employeesHired = new Stack(); //Populate stack employeesHired.Push("Dan Hanks"); employeesHired.Push("Martha Billans"); employeesHired.Push("Phillis Bowman"); // Remove last element string emplyeeFired = (string) employeesHired.Pop(); Stack Class Represents a simple last-in-first-out (LIFO) non-generic collection of objects. Namespace: System.Collections Assembly: mscorlib (in mscorlib.dll) Syntax Visual Basic (Declaration) <SerializableAttribute> _ <ComVisibleAttribute(True)> _ Public Class Stack _ Implements ICollection, IEnumerable, ICloneable Visual Basic (Usage) Dim instance As Stack C# [SerializableAttribute] [ComVisibleAttribute(true)] public class Stack : ICollection, IEnumerable, ICloneable Remarks For the generic version of this collection, see System.Collections.Generic..::.Stack<(Of <(T>)>). Stack is implemented as a circular buffer. The capacity of a Stack is the number of elements the Stack can hold. As elements are added to a Stack, the capacity is automatically increased as required through reallocation. If Count is less than the capacity of the stack, Push is an O(1) operation. If the capacity needs to be increased to accommodate the new element, Push becomes an O(n) operation, where n is Count. Pop is an O(1) operation. Stack accepts nullNothingnullptra null reference (Nothing in Visual Basic) as a valid value and allows duplicate elements. Examples The following example shows how to create and add values to a Stack and how to print out its values. Visual Basic Copy Code Imports System Imports System.Collections Imports Microsoft.VisualBasic Public Class SamplesStack Public Shared Sub Main() ' Creates and initializes a new Stack. Dim myStack As New Stack() myStack.Push("Hello") myStack.Push("World") myStack.Push("!")

' Displays the properties and values of the Stack. Console.WriteLine("myStack") Console.WriteLine(ControlChars.Tab & "Count: {0}", myStack.Count) Console.Write(ControlChars.Tab & "Values:") PrintValues(myStack) End Sub Public Shared Sub PrintValues(myCollection As IEnumerable) Dim obj As [Object] For Each obj In myCollection Console.Write(" {0}", obj) Next obj Console.WriteLine() End Sub 'PrintValues End Class ' This code produces the following output. ' ' myStack ' Count: 3 ' Values: ! World Hello C# using System; using System.Collections; public class SamplesStack { public static void Main() { // Creates and initializes a new Stack. Stack myStack = new Stack(); myStack.Push("Hello"); myStack.Push("World"); myStack.Push("!"); // Displays the properties and values of the Stack. Console.WriteLine( "myStack" ); Console.WriteLine( "\tCount: {0}", myStack.Count ); Console.Write( "\tValues:" ); PrintValues( myStack ); } public static void PrintValues( IEnumerable myCollection ) { foreach ( Object obj in myCollection ) Console.Write( " {0}", obj ); Console.WriteLine(); } } /* This code produces the following output. myStack Count: 3

Values: ! World Hello */ Inheritance Hierarchy System..::.Object System.Collections..::.Stack Microsoft.VisualC..::.SymbolTableStack Thread Safety Public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe. To guarantee the thread safety of the Stack, all operations must be done through the wrapper returned by the Synchronized method. Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads can still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or catch the exceptions resulting from changes made by other threads. Stack Members Represents a simple last-in-first-out (LIFO) non-generic collection of objects. The Stack type exposes the following members. Constructors Name Description Stack Overloaded. Initializes a new instance of the Stack class. MethodsName Clear Clone Contains CopyTo Equals Finalize GetEnumerator GetHashCode GetType MemberwiseClone Peek Pop Push Synchronized ToArray ToString Description Removes all objects from the Stack. Creates a shallow copy of the Stack. Determines whether an element is in the Stack. Copies the Stack to an existing one-dimensional Array, starting at the specified array index. Determines whether the specified Object is equal to the current Object. (Inherited from Object.) Allows an Object to attempt to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. (Inherited from Object.) Returns an IEnumerator for the Stack. Serves as a hash function for a particular type. (Inherited from Object.) Gets the Type of the current instance. (Inherited from Object.) Creates a shallow copy of the current Object. (Inherited from Object.) Returns the object at the top of the Stack without removing it. Removes and returns the object at the top of the Stack. Inserts an object at the top of the Stack. Returns a synchronized (thread safe) wrapper for the Stack. Copies the Stack to a new array. Returns a String that represents the current Object. (Inherited from Object.)

Extension Methods Name Description AsQueryable Converts an IEnumerable to an IQueryable. (Defined by Queryable.) Cast Converts the elements of an IEnumerable to the specified type. (Defined by Enumerable.) OfType Filters the elements of an IEnumerable based on a specified type. (Defined by Enumerable.) Properties Name Count IsSynchronized SyncRoot Description Gets the number of elements contained in the Stack. Gets a value indicating whether access to the Stack is synchronized (thread safe). Gets an object that can be used to synchronize access to the Stack.

TypeForwardedToAttribute TypeForwardedTo is an attribute that allows you to move a type declaration to another assembly, without disrupting users of a previous version of the assembly. It takes one parameter which specifies the destination Type which will be used instead of the type that was in the assembly. The destination type must have the same name and namespace as the type it is replacing. Example If you have a class named Dog in an assembly named Animal namespace Animal { public class Dog { } } You may at a later date decide that Dog would go better in an assembly called Canine However, if you just yank Dog out of Animal any application looking to find Dog in Animal is going to fail. You don’t want applications to fail and you don’t want to have to find all the programs that reference Animal.Dog and require them to change their code and recompile. The TypeForwardedToAttribute makes both these scenarios unnecessary. Move the type declaration to the new assembly In the old assembly, add a reference to the new assembly Add the following to the old assembly: [assembly: TypeForwardedTo( typeof( Animal.Dog ) )]Usually this assembly attribute would be placed in Assembly.cs. Note: The namespace must not change. The following would result in an error: namespace Canine { public class Dog { } } Note: If you are forwarding a type to an assembly that an application does not already have a reference to, adding a TypeForwardedTo will work as long as the new assembly is present. However, once you reopen the application in visual studio, you will have to add a reference to the new assembly. This becomes obvious once you examine the namespace where TypeForwardedTo lives, System.Runtime.CompilerServices. Typecasting Typecasting is the name given to transforming one type into another. There are two types of casting that can be performed on data types, implicit and explicit. Implicit Typecast Implicit casting is performed by the compiler when there is no possible loss of data. This is when a smaller data type is copied into a larger data type - e.g., converting a 16-bit short to a 32-bit integer value. We could also say, implicit casting is used when casting from a basic type to a more general one. Therefore you use implicit typecasts when transforming a square into a rectangle or when transforming a circle into an ellipse. Because the later is the more general, the typecast can be done implicitly. Here is a simple example to how implicit typecasting is done: Int32 iNumber = 185; Double dNumber = 36.485d; dNumber = iNumber; // implicit typecast; dNumber is now 185.0d In this example the typecast can be done implicitly, because real numbers are a superset of integers. This means that Double is more general than Int32. You can implement an implicit typecast in your classes using the implicit keyword. In our example we want to transform a square into a rectangle.

using System; using System.Drawing; public class MySquare { // Remember: please do not make private variables public. // Use accessors instead. private Point pos; private Int32 width; #region Constructors, Methods etc. // ... #endregion #region Methods public Point Position { get { return this.pos; } set { this.pos= value; } } public Int32 Width { get { return this.width; } set { this.width = value; } } #endregion

}

public class MyRectangle { private Point pos; private Int32 width, height; #region Constructors, Methods etc. // ... #endregion #region Implicit Type Conversion public static implicit operator MyRectangle(MySquare Square) { this.pos = Square.Position; this.width = Square.Width; // Because MySquare has no heigth property we set a // default value this.height = Square.Height;

} Now we can do type conversion with ease: MySquare square = new MySquare(...); MyRectangle rectangle = square; Explicit Typecast

} #endregion

Explicit casting requires the use of the cast operator (parentheses) when there is a possible loss of data - e.g., converting a 32-bit integer into an 8-bit byte as in the code below. int fourBytes = 0x000000FE; byte lowestByte = (byte)fourBytes;Using the implicit example, we want to look at the case if there is a data loss on typecasting: MyRectangle rectangle = new MyRectangle(...); MySquare square = rectangle; // Error Because a rectangle may have different width and height, it's not possible to convert the rectangle into a square. We can solve this issue by defining how to handle this case. A possibility to do so is checking if the width and height is equal. If so, the rectangle represents a square and we can convert gracefully. Otherwise, either a type cast exception has to get thrown. public class MySquare { // ... public explicit operator MySquare(MyRectangle Rectangle) { if(Rectangle.Width == Rectangle.Height) { this.Width = Rectangle.Width; // no information lost this.pos = Rectangle.Position; } else { throw new TypeCastException("Rectangle is not square."); } }

} Alternatively we define how the information is transformed, which does not require any exceptions to be thrown. public class MySquare { // ... public explicit operator MySquare(MyRectangle Rectangle) { this.width = Rectangle.Width; this.pos = Rectangle.Position; // ignore the height of the rectangle }

}

Multi-cast Delegate Summary A multi-cast delegate is basically a list of delegates or a list of methods with the same signature. A multi-cast delegate can call a collection of methods instead of only a single method. Remarks .Net delegates are all multi-cast delegates. When calling a multi-cast delegate that returns a value, only the last value will be returned. In order to process every return value, iterate the delegate list and invoke each delegate individually. If one of the methods throws an exception, the delegate call will immediately stop and no other methods in the list will be called.

Code examples Adding multiple delegates to a delegate object public delegate void ExecuteCallback(); class Executioner {

private ExecuteCallback _doExecute; public void AddMultiple() { // Add a delegate to MethodA // This will work even if _doExecute is currently null _doExecute += new Execute( MethodA ); // Add a delegate to MethodB also _doExecute += new Execute( MethodB ); // Add a delegate to MethodC also _doExecute += new Execute( MethodC ); } public void MethodA() { //... } public void MethodB() { //... } public void MethodC() { //... }

} Call a multi-cast delegate // Call the delegate like a method // This will automatically call each delegate that is part of this multi-cast delegate doExecute(); Iterating through a multi-cast delegate manually // Call each delegate in the multi-cast delegate one at a time // In order to handle any exceptions that might occur // Iterating through a delegate manually is needed in // order to continue processing all the delegates even // if one throws an exception // In this example, any exceptions are ignored and // the processing continues with the next delegate // In a real world example, the exception would at least be logged public void IterateAll()

{

} // // // //

if( _doExecute != null ) { foreach( ExecuteCallback doSingleExecute in _doExecute.GetInvocationList() ) { try { doSingleExecute(); } catch { // This delegate threw an exception } } } This technique could also be used for other purposes: To get each return value if the delegate is not void To call all the delegates asynchronously Etc.

Use generic collections Exam sections Collection.Generic interfaces Generic IComparable interface (Refer System Namespace) Generic ICollection interface Generic IList interface Generic IComparer interface Generic IEqualityComparer interface Generic IDictionary interface Generic IEnumerable interface Generic IEnumerator interface IHashCodeProvider interface Generic Dictionary Generic Dictionary class Generic Dictionary.Enumerator structure Generic Dictionary.KeyCollection class Dictionary.KeyCollection.Enumerator structure Generic Dictionary.ValueCollection class Dictionary.ValueCollection.Enumerator structure Generic Comparer Generic Comparer class Generic EqualityComparer class Generic KeyValuePair structure Generic Lists Generic List class Generic List.Enumerator structure Generic SortedList class Generic Queue Generic Queue class Generic Queue.Enumerator structure Generic SortedDictionary class Generic LinkedList Generic LinkedList class Generic LinkedList.Enumerator structure Generic LinkedListNode class

Generic Stack Generic Stack class Generic Stack.Enumerator structure Use specialized collections Specialized String classes StringCollection class StringDictionary class StringEnumerator class Specialized Dictionary HybridDictionary class IOrderedDictionary interface and OrderedDictionary class ListDictionary class Named collections NameObjectCollectionBase class NameObjectCollectionBase.KeysCollection class NameValueCollection class CollectionsUtil BitVector32 structure and BitVector32.Section structure Value types Intrinsic types A value type is a data type which is either one of the intrinsic built-in types, a structure or an enumeration. The intrinsic built-in types are the most commonly used data types, such as int or double. The following table lists some of the built-in value types and includes links to MSDN for reference. The first eight types are used for whole number values and the last three represent real numbers in order of increasing precision. C# Type byte sbyte short ushort int uint long ulong float Point-Value double Value decimal 96 bit .NET Framework Type System.Byte System.SByte System.Int16 System.UInt16 System.Int32 System.UInt32 System.Int64 System.UInt64 System.Single System.Double System.Decimal CLS-Compliant Yes No Yes No Yes No Yes No Yes Yes Yes Description 8 bit unsigned integer 8 bit signed integer 16 bit signed integer 16 bit unsigned integer 32 bit signed integer 32 bit unsigned integer 64 bit signed integer 64 bit unsigned integer 32 bit; IEEE comform Floating64 bit; IEEE comform Floating-Point128 bit Floating-Point-Value (1 bit sign; value; 8 bit exponent; 23 bit unused)

The table shows that each of the built-in types is an alias of the .NET Framework System types. For example, int is an alias of System.Int32. To convert one data type to another requires a cast to be performed. Two other notewothy value types that are commonly used are: C# Type bool char .NET Framework Type System.Boolean System.Char CLS-Compliant Yes Yes Description 1 bit; represents true or false 16 bit Unicode character

A value type variable exists on the stack from the point it is declared until it goes out of scope. For example, when a method returns, all of the local variables inside the method are removed from the stack. In addition, a value type can also exist within an object as one of the object's data members. In that case, its scope is tied to the object that contains it.

Declaring value types A value type can be declared without being initialized, however it cannot be used unless a value is assigned to it. For example the following code will cause an error of type "Use of unassigned local variable". public int foo() { int a; return a; } This is because the value of a value type cannot contain the value null. If this is required, use a nullable type instead. This can be overcome in two ways. The first is simply to assign a value at declaration: public int foo() { int a = 12; return a; }The second way is through the use of the new keyword. When a value type is created using the new keyword, its value will default to a known state by its default constructor. Each value type has an implicit default constructor that initializes the default value of that particular type. For information on the default values of value types, refer to the Default Values Table. public int foo() { int a = new int(); // Default value of 0 return a; } Copying value types When one value type variable is assigned to another, the value is copied. This can be seen in the following example: // Declare and initialize a to 10 int a = 10; // Declare and initialize b to a (10) int b = a; // a is now 15, but b is still 10 a = 15;The second statement declares a new integer named b and assigns it to a. The value of a is passed to b as a copy of the original value. Now when a is altered in the third statement, it has no effect on the value of b. Passing parameters by value When you pass a variable to a method, this means you are passing a copy of the variable to the method. Any change to the parameter that takes place inside the method has no effect on the original data stored in the variable. In the following example, the value of myInt will still be five after the method has been called. public void SquareIt(int x) { x *= x; } public static void Main() { int myInt = 5; SquareIt(myInt); // Passing myInt by value. }

Passing parameters by reference If you want the called method to change the value of the parameter, you have to pass it by reference, using the ref or out keywords. In the following example, the value of myInt will equal 25 after the method has been called. public void SquareIt(ref int x) { x *= x; } public static void Main() { int myInt = 5; SquareIt(ref myInt); // Passing myInt by reference. } Visual C# Best Practices You should mark functions explicitly which are using non-CLR Types with System.CLSCompliantAttribute. [CLSCompliant(false)] public ushort foo() { ... }This will generate a warning message when compiling, which makes it possible to find otherwise hidden interop-errors when you working on a .Net Project using various Programming-Languages which are originally not created for .Net. ref The ref keyword causes arguments to be passed by reference. The effect is that any changes to the parameter in the method will be reflected in that variable when control passes back to the calling method. Note: Do not confuse the concept of passing by reference with the concept of reference types. The two concepts are not related; a method parameter can be modified by ref regardless of whether it is a value type or a reference type. Therefore, there is no boxing of a value type when it is passed by reference. To use a ref parameter, both the method definition and the calling method must explicitly use the ref keyword. For example: C# class RefExample { static void Method(ref int i) { i = 44; } static void Main() { int val = 0; Method(ref val); // val is now 44 } } An argument passed to a ref parameter must first be initialized. This differs from out, whose arguments do not have to be explicitly initialized before they are passed. For more information, see out. Although the ref and out keywords cause different run-time behavior, they are not considered part of the method signature at compile time. Therefore, methods cannot be overloaded if the only difference is that one method takes a ref argument and the other takes an out argument. The following code, for example, will not compile: C# class CS0663_Example {

// Compiler error CS0663: "Cannot define overloaded // methods that differ only on ref and out." public void SampleMethod(out int i) { } public void SampleMethod(ref int i) { } } Overloading can be done, however, if one method takes a ref or out argument and the other uses neither as in the following example: C# class RefOverloadExample { public void SampleMethod(int i) { } public void SampleMethod(ref int i) { } } Properties are not variables. They are actually methods, and therefore cannot be passed as ref parameters. Example Passing value types by reference, as demonstrated earlier in this topic, is useful, but ref is also useful for passing reference types. This allows called methods to modify the object to which the reference refers because the reference itself is being passed by reference. The following sample shows that when a reference type is passed as a ref parameter, the object itself can be changed. For more information, see Passing Reference-Type Parameters (C# Programming Guide). C# class RefExample2 { static void Method(ref string s) { s = "changed"; } static void Main() { string str = "original"; Method(ref str); Console.WriteLine(str); } } // Output: changed out The out keyword causes arguments to be passed by reference. This is like the ref keyword, except that ref requires that the variable be initialized before it is passed. To use an out parameter, both the method definition and the calling method must explicitly use the out keyword. For example: C# class OutExample { static void Method(out int i) { i = 44; } static void Main() { int value; Method(out value);

} }

// value is now 44

Although variables passed as out arguments do not have to be initialized before being passed, the called method is required to assign a value before the method returns. Although the ref and out keywords cause different run-time behavior, they are not considered part of the method signature at compile time. Therefore, methods cannot be overloaded if the only difference is that one method takes a ref argument and the other takes an out argument. The following code, for example, will not compile: C# class CS0663_Example { // Compiler error CS0663: "Cannot define overloaded // methods that differ only on ref and out." public void SampleMethod(out int i) { } public void SampleMethod(ref int i) { } } Overloading can be done, however, if one method takes a ref or out argument and the other uses neither, like this: C# class OutOverloadExample { public void SampleMethod(int i) { } public void SampleMethod(out int i) { i = 5; } } Properties are not variables and therefore cannot be passed as out parameters. For information about passing arrays, see Passing Arrays Using ref and out (C# Programming Guide). Example Declaring an out method is useful when you want a method to return multiple values. The following example uses out to return three variables with a single method call. Note that the third argument is assigned to null. This enables methods to return values optionally. C# class OutReturnExample { static void Method(out int i, out string s1, out string s2) { i = 44; s1 = "I've been returned"; s2 = null; } static void Main() { int value; string str1, str2; Method(out value, out str1, out str2); // value is now 44 // str1 is now "I've been returned" // str2 is (still) null; } }

Value vs Reference An example This example shows the difference between how a value type works in memory, and how a reference does. First we define a new Value Type and a new Reference Type. class ReferenceType { public Int32 X; } struct ValueType { public Int32 X; }Now we want to use these types to show how they work: ReferenceType ref1 = new ReferenceType(); ValueType val1 = new ValueType(); ref1.X = 5; val1.X = 5;The layout of the memory at this point looks something like the following:

If we now make copies of these values using the following code: ReferenceType ref2 = ref1; ValueType val2 = val2;The layout of the memory now looks something like the following:

If we now change the value of each of the new copies using the following code: Ref2.X = 8; Val2.X = 8;The layout of the memory now looks something like the following:

Summary A variable that is of type value directly contains a value. Assigning a variable of type value to another variable of type value COPIES that value. A variable of type reference, points to a place in memory where the actual object is contained. Assigning a variable of type reference to another variable of type reference copies that reference (it tells the new object where the place in memory is), but does not make a copy of the object. Value types are stored on the stack. Reference types are stored on the heap. Value types can not contain the value null. * Reference types can contain the value null. Value types have a default implied constructor that initializes the default value. Reference types default to a null reference in memory. Value types derive from System.ValueType. Reference types derive from System.Object. Value types cannot derive a new type from an existing value type, except for structs. Reference types can derive a new type from an existing reference type as well as being able to implement interfaces. Changing the value of one value type does not affect the value of another value type. Changing the value of one reference type MAY change the value of another reference type. The nullable type (only in .NET 2.0) can be assigned the value null. const, static and readonly Within a class, const, static and readonly members are special in comparison to the other modifiers. const vs. readonly

const and readonly perform a similar function on data members, but they have a few important differences. const A constant member is defined at compile time and cannot be changed at runtime. Constants are declared as a field, using the const keyword and must be initialized as they are declared. For example; public class MyClass { public const double PI = 3.14159; } PI cannot be changed in the application anywhere else in the code as this will cause a compiler error. Constants must be of an integral type (sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, bool, or string), an enumeration, or a reference to null. Since classes or structures are initialized at run time with the new keyword, and not at compile time, you can't set a constant to a class or structure. Constants can be marked as public, private, protected, internal, or protected internal. Constants are accessed as if they were static fields, although they cannot use the static keyword. To use a constant outside of the class that it is declared in, you must fully qualify it using the class name. readonly A read only member is like a constant in that it represents an unchanging value. The difference is that a readonly member can be initialized at runtime, in a constructor as well being able to be initialized as they are declared. For example: public class MyClass { public readonly double PI = 3.14159; }or public class MyClass { public readonly double PI; public MyClass() { PI = 3.14159; }

} Because a readonly field can be initialized either at the declaration or in a constructor, readonly fields can have different values depending on the constructor used. A readonly field can also be used for runtime constants as in the following example: public static readonly uint l1 = (uint)DateTime.Now.Ticks;Notes readonly members are not implicitly static, and therefore the static keyword can be applied to a readonly field explicitly if required. A readonly member can hold a complex object by using the new keyword at initialization. readonly members cannot hold enumerations. static Use of the static modifier to declare a static member, means that the member is no longer tied to a specific object. This means that the member can be accessed without creating an instance of the class. Only one copy of static fields and events exists, and static methods and properties can only access static fields and static events. For example: public class Car { public static int NumberOfWheels = 4;

} The static modifier can be used with classes, fields, methods, properties, operators, events and constructors, but cannot be used with indexers, destructors, or types other than classes. static members are initialized before the static member is accessed for the first time, and before the static constructor, if any is called. To access a static class member, use the name of the class instead of a variable name to specify the location of the member. For example: int i = Car.NumberOfWheels; enum The Basics An enum is a value type with a set of related named constants often referred to as an enumerator list. They allow code to look a lot cleaner and easier to read by getting rid of "magic numbers", that is to say, they get rid of numbers which have a purpose within a module of code, but make the code harder to read. If a single number needs a definition to make it easier to read then use a constant as shown below. public const int North = 0; However, if more than one related number needs a definition, then use an enumeration. Declaration An enum is declared as follows: [attributes] [modifiers] enum identifier [:base-type] { enumerator-list [,] } The attributes is optional and is used to hold additional declarative information. The modifier is optional. The allowed modifiers are new, public, protected, internal and private. The keyword enum must be followed by an identifier that names the enum. The base-type of an enumeration may be one of the following; byte, sbyte, short, ushort, int, uint, long or ulong. If no base-type is declared, than the default of int is used. The enumerator-list contains the identifiers which are separated by commas (optionally including a value assignment). The first enumerator begins at zero by default and each enumerator following is increased by 1. This can be overridden so that each member of the enumerator-list contains its own unrelated value (see second example below). Two items in an enumeration can hold the same value, however, this will cause problems if you use an automated switch statement where all elements are added. Example 1 – A simple enumeration An application may need to work with directions. Instead of using four numbers to represent the major directions, an enumeration works better. The numbers then become irrespective as the directions are named. enum Direction { North, East, South, West } Example 2 – Number specific Now consider the same enumeration, but with each direction holding the value clockwise that they are from North. enum Direction { North = 0,

} We would use the enumeration in the same manner, but the values have different meanings. Casting To get the underlying value of an item in an enumerator-list, you need to have an explicit cast to convert it from the enum type to its integral type. The following code displays this and makes use of the enum in example 2. static void Main(string[] args) { Console.WriteLine("-------------------------------"); Console.WriteLine("Direction Enum Members by Name:"); Console.WriteLine("-------------------------------"); // get a list of member names from Direction enum, // figure out the numeric value, and display foreach (string direction in Enum.GetNames(typeof(Direction))) { Console.WriteLine("Direction Member: {0}\n Value: {1}", direction, (int)Enum.Parse(typeof(Direction), direction)); } } And here is the output ------------------------------Direction Enum Members by Name: ------------------------------Direction Member: North Value: 0 Direction Member: East Value: 90 Direction Member: South Value: 180 Direction Member: West Value: 270 Some useful methods Enum.GetName - retrieves the name of the constant in the enumeration that has a specific value. Enum.GetNames - retrieves an array of the names of the constants in the enumeration. Enum.GetValues - retrieves an array of the values of the constants in the enumeration. Enum.IsDefined - returns an indication whether a constant with a specified value exists in a specified enumeration. enum The enum keyword is used to declare an enumeration, a distinct type that consists of a set of named constants called the enumerator list. Usually it is best to define an enum directly within a namespace so that all classes in the namespace can access it with equal convenience. However, an enum can also be nested within a class or struct. By default, the first enumerator has the value 0, and the value of each successive enumerator is increased by 1. For example: enum Days {Sat, Sun, Mon, Tue, Wed, Thu, Fri}; In this enumeration, Sat is 0, Sun is 1, Mon is 2, and so forth. Enumerators can have initializers to override the default values. For example:

East = 90, South = 180, West = 270

enum Days {Sat=1, Sun, Mon, Tue, Wed, Thu, Fri}; In this enumeration, the sequence of elements is forced to start from 1 instead of 0. However, we strongly recommend that an enum contain a constant with a value of 0. For more information, see Enumeration Types (C# Programming Guide). Every enumeration type has an underlying type, which can be any integral type except char. The default underlying type of the enumeration elements is int. To declare an enum of another integral type, such as byte, use a colon after the identifier followed by the type: enum Days : byte {Sat=1, Sun, Mon, Tue, Wed, Thu, Fri}; The approved types for an enum are byte, sbyte, short, ushort, int, uint, long, or ulong. A variable of type Days can be assigned any value in the range of the underlying type; the values are not limited to the named constants. The default value of an enum E is the value produced by the expression (E)0. Note: An enumerator may not contain white space in its name. The underlying type specifies how much storage is allocated for each enumerator. However, an explicit cast is necessary to convert from enum type to an integral type. For example, the following statement assigns the enumerator Sun to a variable of the type int by using a cast to convert from enum to int: int x = (int)Days.Sun; When you apply System..::.FlagsAttribute to an enumeration that contains some elements combined with a bitwise OR operation, you will notice that the attribute affects the behavior of the enum when it is used with some tools. You can notice these changes when you use tools such as the Console class methods, the Expression Evaluator, and so forth. (See example 3). Robust Programming Just as with any constant, all references to the individual values of an enum are converted to numeric literals at compile time. This can create potential versioning issues as described in Constants (C# Programming Guide). Assigning additional values to new versions of enums, or changing the values of the enum members in a new version, can cause problems for dependant source code. Enum values are used often in switch statements. If additional elements have been added to the enum type, the test for default values can return true unexpectedly. If other developers will be using your code, you should provide guidelines about how their code should react if new elements are added to any enum types. Example In this example, an enumeration, Days, is declared. Two enumerators are explicitly converted to integer and assigned to integer variables. C# public class EnumTest { enum Days { Sun, Mon, Tue, Wed, Thu, Fri, Sat }; static void Main() { int x = (int)Days.Sun; int y = (int)Days.Fri; Console.WriteLine("Sun = {0}", x); Console.WriteLine("Fri = {0}", y); }

} /* Output: Sun = 0 Fri = 5

*/ In this example, the base-type option is used to declare an enum whose members are of the type long. Notice that even though the underlying type of the enumeration is long, the enumeration members must still be explicitly converted to type long by using a cast. C# public class EnumTest2 { enum Range : long { Max = 2147483648L, Min = 255L }; static void Main() { long x = (long)Range.Max; long y = (long)Range.Min; Console.WriteLine("Max = {0}", x); Console.WriteLine("Min = {0}", y); } } /* Output: Max = 2147483648 Min = 255 */ The following code example illustrates the use and effect of the System..::.FlagsAttribute attribute on an enum declaration. C# [Flags] public enum CarOptions { SunRoof = 0x01, Spoiler = 0x02, FogLights = 0x04, TintedWindows = 0x08, } class FlagTest { static void Main() { CarOptions options = CarOptions.SunRoof | CarOptions.FogLights; Console.WriteLine(options); Console.WriteLine((int)options); } } /* Output: SunRoof, FogLights 5 */ Comments Notice that if you remove FlagsAttribute, the example will output the following: 5 5 C# Language Specification

For more information, see the following sections in the C# Language Specification: 1.10 Enums 6.2.2 Explicit Enumeration Conversions 14 Enums struct The Basics A struct is a simple user-defined type, a lightweight alternative to a class. They support access modifiers, constructors, indexers, methods, fields, nested types, operators, and properties. They may not declare a default constructor (a constructor with no parameters) or a destructor, however you can declare constructors, but they must take parameters. Unlike classes, structures do not support compile-time initialization of instance fields, they cannot derive from anything other than System.ValueType and they cannot be the base of another class. However, they may implement an Interface. They can be instantiated without using a new operator. Structures take up fewer resources in memory than classes, so when you have a small, frequently used class, give some thought to using a struct instead. Note though that performance can suffer when using structures in situations where reference types are expected due to boxing and unboxing. struct members may not be declared protected. Declaration A struct is declared as follows: [attributes] [modifiers] struct identifier [:interfaces] { body [;] } The attributes is optional and is used to hold additional declarative information. The modifier is optional. The allowed modifiers are new, static, virtual, abstract, override, and a valid combination of the four access modifiers (public, protected, internal and private). The keyword struct must be followed by an identifier that names the struct. The interfaces list is optional. The list contains the interfaces implemented by the struct, all separated by commas. The body contains the member declarations. Example 1 - A coordinate Imagine that you had a need for a class to define a coordinate. This is a good candidate for a structure. public struct Coords { public int X, Y; public Coords(int p1, int p2) { X = p1; Y = p2; } // Override the ToString method so the value appears in text public override string ToString() { return String.Format("({0},{1})", X, Y); }

} Which can be created in the following manner: class Program { static void Main(string[] args)

{ } }

Coords coord = new Coords(3,4); Console.WriteLine(coord.ToString());

Example 2 - A complex number A complex number has both real and imaginary parts, for instance 1 + 2i. This can be implemented as a simple struct. public struct Complex { public int real; public int imaginary; public Complex(int r, int i) { real = r; imaginary = i; } public double Magnitude() { return System.Math.Sqrt(real * real + imaginary * imaginary); } // Override the ToString method so the value appears in text public override string ToString() { return (String.Format("{0}{1}i", real.ToString("#;-#;+0"), imaginary.ToString("+#;-#;+0"))); } } Which can be created in the following manner: class Program { static void Main(string[] args) { Complex comp = new Complex(3,4); Console.WriteLine(comp.ToString() + " with magnitude " + comp.Magnitude()); } } Which prints 3+4i with magnitude 5 Structs Structs are defined by using the struct keyword, for example: C# public struct PostalAddress { // Fields, properties, methods and events go here... } Structs share most of the same syntax as classes, although structs are more limited than classes: Within a struct declaration, fields cannot be initialized unless they are declared as const or static.

A struct may not declare a default constructor (a constructor without parameters) or a destructor. Structs are copied on assignment. When a struct is assigned to a new variable, all the data is copied, and any modification to the new copy does not change the data for the original copy. This is important to remember when working with collections of value types such as Dictionary<string, myStruct>. Structs are value types and classes are reference types. Unlike classes, structs can be instantiated without using a new operator. Structs can declare constructors that have parameters. A struct cannot inherit from another struct or class, and it cannot be the base of a class. All structs inherit directly from System.ValueType, which inherits from System.Object. A struct can implement interfaces. A struct can be used as a nullable type and can be assigned a null value.

Sign up to vote on this title
UsefulNot useful