用户定义类型的强制转换

在类型转换的过程中,有些类型之间可以直接转换(如int->double),而有些就必须显示强制转换(如double->int)。类型转换遵循这样的规则:

无论源变量中存什么值,转换成目标变量总是安全的(不会丢失数据,不会异常等等),那么就可以直接转换(隐式转换)。
反之,如果转换成目标变量有可能会出错,如数据丢失或者异常等等,那么就必须显示的强制转换。

一、 自定义类型转换

    我们都知道,当想把一个int类型转换成一个double类型的数据的时候,直接就可以完成。我们考虑一下这种情况,如果我们有一个描述长方体的结构体,里面保存了长、宽和高。想要获取的体积会怎么做?很明显首先想到的是在机构体里面定义一个方法,返回体积。如下:

public struct Cube
    {
        public Cube(double length, double width, double height)
        {
            this.Length = length;
            this.Height = height;
            this.Width = width;
        }

        public double Length;

        public double Height;

        public double Width;

        public double GetVolume()
        {
            return Length * Height * Width;
        }
    }

我想是不是可以像int到double直接转换就得到体积呢?答案当然是可以的,可以使用自定义类型转换(实际上我们不应该这么做,因为这会使代码变得不好理解)。自定义类型转换定义的语法如下:

public static explicit operator T1(T2 value);
public static implicit operator T1(T2 value);

T1是目标类型,T2是源类型。explicit和implicit表示是要显式转换还是隐式转换。因为类型转换和实例无关,所以我们必须定义为public static。我们修改一下结构体代码,使它可以直接转换成double类型:

public struct Cube
    {
        public Cube(double length, double width, double height)
        {
            this.Length = length;
            this.Height = height;
            this.Width = width;
        }

        public double Length;

        public double Height;

        public double Width;

        public double GetVolume()
        {
            return Length * Height * Width;
        }

        public static implicit operator double(Cube cube)
        {
            return cube.GetVolume();
        }

        public static explicit operator Cube(double d)
        {
            Cube b = new Cube();
            b.Height = b.Width = b.Length = Math.Pow(d, 1/3d);
            return b;
        }

        public override string ToString()
        {
            return string.Format("Length:{0}  Height:{1} Width:{2}", Length, Height, Width);
        }
    }

在结构体中定义了由Cube隐式转换成double,double显示转换成Cube(假设doube->Cube时为立方体)。

在mian方法中添加测试代码:

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();
        }

 

运行得到结果:

volume:60
Length:3  Height:3 Width:3

 

可以看到,由Cube转换成double时可以直接转换,而从double转换成Cube必须显式的强制转换。

到这里我们实现了double和结构体之间的类型转换。对于类和类、或者类和结构体等等之间的类型转换的实现方式是一样的。但是基类和派生类之间不能定义强制类型转换,因为它们的类型转换已经存在。

 

 

 

posted on 2012-08-22 23:49  细小猛  阅读(594)  评论(0编辑  收藏  举报