zoukankan      html  css  js  c++  java
  • C#中的转换

    11.3  转换

    到目前为止,在需要把一种类型转换为另一种类型时,使用的都是类型转换。而这并不是唯一的方式。

    在计算过程中,int可以采用相同的方式隐式转换为long或double,还可以定义所创建的类(隐式或显式)转换为其他类的方式。

    为此,可以重载转换运算符,其方式与本章前面重载其他运算符的方式相同。

    11.3.1  重载换算运算符

    除了重载如上所述的数学运算符之外,还可以定义类型之间的隐式和显式转换。

    如果要在不相关的类型之间转换,这是必须的,例如,如果在类型之间没有继承关系,也没有共享接口,这是必须的。

    下面定义ConvClass1和ConvClass2之间的隐式转换,即编写下述代码:

    ConvClass1 op1 = new ConvClass1();
    ConvClass2 op2 = op1;

    另外,还可以定义一个显式转换,在下面的代码中调用

     ConvClass1 op3 = new ConvClass1();
     ConvClass2 op4 = (ConvClass2)op3;

    例如,考虑下面的代码

    public class ConvClass1
        {
            public int val;
            public static implicit operator ConvClass2(ConvClass1 op1)//隐式转换
            {
                ConvClass2 retrunVal = new ConvClass2();
                retrunVal.val = op1.val;
                return retrunVal;
            }
        }
    
        public class ConvClass2
        {
            public double val;
            public static explicit operator ConvClass1(ConvClass2 op2)//显式转换
            {
                ConvClass1 returnVal = new ConvClass1();
                returnVal.val = (int)op2.val;
                return returnVal;
            }
        }

    其中,ConvClass1包含一个int值,ConvClass2包含一个double值。

    int值可以隐式转换为double值,所以可以在ConvClass1和ConvClass2之间定义一个隐式转换。

    但是反过来就不行了,应把ConvClass2和ConvClass1之间的转换定义为显式转换。

    在代码中,用关键字implicit和explicit来指定这些转换,如上所示。对于这些类,下面的代码就很好:

                try
                {
                    ConvClass1 op1 = new ConvClass1();
                    op1.val = 3;
                    ConvClass2 op2 = op1;
                    Console.WriteLine(string.Format("op2.val = {0}", op2.val));
    
                    ConvClass2 op3 = new ConvClass2();
                    op3.val = 3e15;
                    ConvClass1 op4 = (ConvClass1)op3;
                    Console.WriteLine(string.Format("op4.val = {0}", op4.val));
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }

    在第二个转换中,没有做数据转换的合法性检查,数据会丢失。

    本来是3e15但是转换的时候,数据溢出了。超出了int的范围。

    解决防范:可以使用checked关键字,进行检查:

     public class ConvClass2
        {
            public double val;
            public static explicit operator ConvClass1(ConvClass2 op2)
            {
                ConvClass1 returnVal = new ConvClass1();
                checked { returnVal.val = (int)op2.val; }
                return returnVal;
            }
        }

    如果在显示转换中使用了checked关键字,之前的转换就会产生异常。

    13.2    as 运算符

    as运算符使用下面的语法,把一种类型转换为指定的引用类型

    <operand> as <type>

    这只适用于下列情况:

    <operand>的类型是<type>类型

    <operand>可以隐式转换为<type>类型

    <operand>可以封箱到<type>类型中

    如果不能从<operand>转换为<type>,则表达式的结果就是null。

    注意,基类到派生类的转换可以使用显示转换来进行,但这并不总是有效的。考虑前面示例中的两个类ClassA和ClassD。其中ClassD派生于ClassA:

     interface IMyInterface
        { }
        class ClassA : IMyInterface
        { }
        class ClassD : ClassA
        { }

    以下的代码使用as运算符把obj1中存储的ClassA实例转换为ClassD实例:

    ClassA obj1 = new ClassA();
    ClassD obj2 = obj1 as ClassD;

    则obj2的结果为null

    还可以使用多态性把ClassD实例存储在ClassA类型的变量中。下面的代码演示了这个方面,ClassA类型的变量包含ClassD类型的实例,使用as运算符把ClassA类型的变量转换为ClassD类型。

    ClassD obj1 = new ClassD();
    ClassA obj2 = obj1;
    ClassD obj3 = obj2 as ClassD;

    其中obj3包含与obj1相同的对象引用,而不是null。

    因此,as运算符非常有用,因为下面使用简单类型转换的代码会抛出一个异常:

    ClassA obj1 = new ClassA();
    ClassD obj2 = (ClassD)obj1;

    而as表达式只会把null赋予obj2,不会抛出异常。这表示,下面的代码在C#应用程序中是很常见的

    (使用本章前面开发的2个类:Animal和派生于Animal的一个类Cow)

            public void MilkCow(Animal myAnimal)
            {
                Cow myCow = myAnimal as Cow;
                if (myCow != null)
                {
                    myCow.Milk();
                }
                else
                {
                    Console.WriteLine("{0} isn't a cow,and so can't be milked.", myAnimal.Name);
                }
            }

    这要比检查异常要简单得多!

  • 相关阅读:
    HDU 1022 Train Problem I
    HDU 1702 ACboy needs your help again!
    HDU 1294 Rooted Trees Problem
    HDU 1027 Ignatius and the Princess II
    HDU 3398 String
    HDU 1709 The Balance
    HDU 2152 Fruit
    HDU 1398 Square Coins
    HDU 3571 N-dimensional Sphere
    HDU 2451 Simple Addition Expression
  • 原文地址:https://www.cnblogs.com/chucklu/p/4418256.html
Copyright © 2011-2022 走看看