LilianChen C#:数据类型转换
在类型转换过程中,有些类型之间可以直接转换(如int->double),而有些就必须显示强制转换(如double->int),类型转换遵循这样的规则:
无论源变量中存什么值,转换成目标变量总是安全的(不会丢失数据,不会异常等等),那么就可以直接转换(隐式转换)。反之,如果转换成目标变量可能会出错,那么久必须显示的强制转换。
1. 用户定义的数据类型转换:
用户定义类型转换的语法如下:
public static explicit operator T1(T2 value);
public static implicit operator T1(T2 value);T1是目标类型,T2是源类型。explicit和implicit表示是要显示转换还是隐式转换。因为类型转换和实例无关,所以我们必须定义为public static。
示例1:
using System;
namespace ConsoleApplication22
{
class Program
{
static void Main(string[] args)
{
try
{
Currency balance = new Currency(50, 35);
Console.WriteLine(balance);
Console.WriteLine("balance is " + balance);
Console.WriteLine("balance is (using ToString()) " + balance.ToString());
float balance2 = balance;
Console.WriteLine("After converting to float, = " + balance2);
balance = (Currency)balance2;
Console.WriteLine("After converting back to Currency, = " + balance);
balance = (Currency)(-50.5);
Console.WriteLine("Result is " + balance.ToString());
}
catch (Exception e)
{
Console.WriteLine("Exception occurred: " + e.Message);
}
Console.ReadLine();
}
}
struct Currency
{
public uint Dollars;
public ushort Cents;
public Currency(uint dollars, ushort cents)
{
this.Dollars = dollars;
this.Cents = cents;
}
public override string ToString()
{
return string.Format("${0}.{1,-2:00}", Dollars, Cents);
}
public static implicit operator float(Currency value)
{
return value.Dollars + (value.Cents / 100.0f);
}
public static explicit operator Currency(float value)
{
checked
{
uint dollars = (uint)value;
ushort cents = Convert.ToUInt16((value - dollars) * 100);
return new Currency(dollars, cents);
}
}
}
}
注:示例1中显示转换cents时没有直接使用代码:ushort cents = (ushort)((value-dollars)*100); 是为了避免圆整错误
示例2:
using System;
namespace ConsoleApplication23
{
class Program
{
static void Main(string[] args)
{
Cube cube = new Cube(2, 5, 6);
double volume = cube;
Console.WriteLine("volume: {0}", volume);
volume = 27;
cube = (Cube)volume;
Console.WriteLine(cube.ToString());
Console.ReadLine();
}
}
public struct Cube
{
double Length;
double Width;
double Height;
public Cube(double length, double width, double height)
{
this.Length = length;
this.Width = width;
this.Height = height;
}
public double GetVolume()
{
return Length * Width * Height;
}
public override string ToString()
{
return String.Format("Lenght: {0} Width: {1} Height: {2}", Length, Width, Height);
}
public static implicit operator double(Cube cube)
{
return cube.GetVolume();
}
public static explicit operator Cube(double d)
{
Cube b = new Cube();
b.Length = b.Width = b.Height = Math.Pow(d, 1 / 3d);
return b;
}
}
}
2. 类之间的数据类型转换
定义不同结构或类之间的数据类型转换时允许的,但是有两个限制:
•如果某个类直接或间接继承了另一个类,就不能定义这两个类之间的数据类型转换(这些类型的类型转换已经存在)
•数据类型转换必须在源或目标数据类型的内部定义。
3. 基类和派生类之间的数据类型转换
•源和目标的数据类型都是引用类型
考虑两个类MyBase和MyDerived,其中MyDerived直接或间接派生于MyBase。
首先,从MyDerived到 MyBase的转换(派生类转换为基类):
MyDerived derivedObject = new MyDerived();
MyBase baseCopy = derivedObject;
namespace ConsoleApplication24
{
class Program
{
static void Main(string[] args)
{
MyBase derivedObject = new MyDerived();
MyBase baseObject = new MyBase();
MyDerived derivedCopy1 = (MyDerived)derivedObject; // ok
MyDerived derivedCopy2 = (MyDerived)baseObject; // Throw exception:Unable to cast object of type 'ConsoleApplication24.MyBase' to type 'ConsoleApplication24.MyDerived'
}
}
public class MyDerived : MyBase
{ }
public class MyBase
{
}
}