IConvertible


Jump to: navigation, search
Exam Prep. Guides
Exam 70-536 Study Guide

1. Types and collections

2. Process, threading,…
3. Embedding features
4. Serialization, I/O
5. .NET Security
6. Interop., reflection,…
7. Global., drawing, text

edit

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 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

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


MSDN references

IConvertible Interface


Previous_Page_.gif Next_Page_.gif

Share this page
  • del.icio.us
  • Facebook
  • Google+
  • StumbleUpon