IConvertible
Microsoft .NET Framework, ASP.NET, Visual C# (CSharp, C Sharp, C-Sharp) Developer Training, Visual Studio
Contents |
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.
Syntax
Declaration syntax
[ComVisibleAttribute(true)] [CLSCompliantAttribute(false)] public interface IConvertible
Method syntax
UNDER CONSTRUCTION
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
InvalidCastExceptionif it would not make sense to convert to this type - Define a private method to calculate the class' value
- Use the
Convertclass to convert the desired numeric value to the other CLR types
- Throw
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 }
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; }
Result
Boolean: True Byte: 3 Char: Invalid Cast DateTime: Invalid Cast DBNull: Invalid Cast Decimal: 2.59807621135332 Double: 2.59807621135332 Empty: Invalid Cast Int16: 3 Int32: 3 Int64: 3 Object: Interfaces.Vector SByte: 3 Single: 2.598076 String: Magnitude: 2.59807621135332 UInt16: 3 UInt32: 3 UInt64: 3