System.IConvertible
این interface شما رو موظف می کنه که نه یک متد بلکه یک کوه متد به کلاستون اضافه کنید:
public TypeCode GetTypeCode()
public bool ToBoolean(IFormatProvider provider)
public byte ToByte(IFormatProvider provider)
public char ToChar(IFormatProvider provider)
public DateTime ToDateTime(IFormatProvider provider)
public decimal ToDecimal(IFormatProvider provider)
public double ToDouble(IFormatProvider provider)
public short ToInt16(IFormatProvider provider)
public int ToInt32(IFormatProvider provider)
public long ToInt64(IFormatProvider provider)
public sbyte ToSByte(IFormatProvider provider)
public float ToSingle(IFormatProvider provider)
public string ToString(IFormatProvider provider)
public object ToType(Type conversionType, IFormatProvider provider)
public ushort ToUInt16(IFormatProvider provider)
public uint ToUInt32(IFormatProvider provider)
public ulong ToUInt64(IFormatProvider provider)
در بین اونا دو تا از متدها با دیگران متفاوتند: GetTypeCode و ToType
بقیه شبیه هم به نظر می رسند.
هدف از این interface اینه که کلاس رو موظف کنه که برای user امکاناتی رو برای تبدیل object های ساخته شده از این کلاس رو به نوع های اولیه فراهم کنه:
Boolean, SByte, Byte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Decimal, DateTime, Char, and String.
مثلا ToInt32 وظیفه داره که شی را به نوع int، کانورت کنه.
مزیت بارز این کار اینه که وقتی شما این interface رو پیاده سازی می کنید، اشیا از نوع کلاس شما می تونند توسط System.Convert معروف به انواع اولیه نظیر رشته و عدد و ... تبدیل بشند.
در اینجا چون تعداد توابع زیاده فرق پیاده سازی Explicit و غیر Explicit بیشتر مشخصه.
در ضمن از پارامتر IFormatProvider هم نترسید. اگه ازش خوشتون نمیاد نیازی نیست ازش استفده کنید. بگذارید دکوری باقی بمونه.
هر چند مثال های MSDN همیشه خوب نیستند اما این یکی جالبه. یک کلاس ساخته که اعداد مختلط رو نگه می داره و به ما اجازه میده اون رو به نوع های مختلف Convert کنیم:
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 String.Format("({0}, {1})", x, y);
}
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;
}
}
}
}
یک حرف هایی هم در مورد استثنائات مربوط به این interface گفته شده که حوصله ندارم ترجمه کنم. دوست داشتید به خود MSDN رجوع کنید:
http://msdn.microsoft.com/en-us/libr...nvertible.aspx