• C#中的自定义类型转换


    C#中一个继承自C++的优良特性是可以自定义类型转换。
    以前在C++中这样写:
    class CBrush{
    //摘自MFC中CBrush类的部分代码。
    public:
    operator HBRUSH() const;
    };
    在C#中也有类似的写法,不过要注意的是C#中这种类型转换函数必须是静态的,相比较与C++,C++中的类型转换则就没有这样的限制。
    此外,自定义类型转换可以设置修饰符explicit或implicit。explicit表示显式,也就是在使用这个转换时必须显式写在代码中。implicit修饰符表示隐式,隐式使用即使用时不必要显式写出来,如下例:
    class A{
    public static explicit operator A(B b){省略内容} //这是一个显式转换
    public static implicit operator B(A a){省略内容} //这是一个隐式转换
    }
    B b
    =new B();
    A a
    =(A)b; //显式使用显式转换
    b=a; //隐式使用隐式转换
    自定义转换还需要注意的一点与as这个运算符有关。as一般情况下相当于 expression is type ? (type)expression : (type)null但只计算一次 expressionas 运算符只执行引用转换和装箱转换。as 运算符无法执行其他转换,如用户定义的转换,这类转换应使用强制转换表达式来执行。
    然后就是发现在值类型和引用类型之间的自定义转换比较麻烦,装箱和不装箱的值类型在转换时的行为是有区别的。
    下面的MyInt是一个引用类型,用作测试和值类型int之间的转换。
       
    自定义转换测试
    class MyInt
    {
    int data;
    public MyInt():this(10){}
    public MyInt(int val)
    {
    data
    = val;
    }
    public static explicit operator int(MyInt x)
    {
    return x.data;
    }
    public static explicit operator MyInt(int x)
    {
    MyInt a
    = new MyInt();
    a.data
    = x;
    return a;
    }
    public override string ToString()
    {
    return data.ToString();
    }
    }
    static void Main(string[] args)
    {
    try
    {
    MyInt myInt
    = new MyInt();
    int t = 100;
    myInt
    = (MyInt)t; //执行自定义转换 operator MyInt(int)
    Console.WriteLine("myInt={0}", (myInt == null ? "null" : myInt.ToString())); //myInt=100
    int x = (int)myInt; //执行自定义转换 operator int(MyInt)
    Console.WriteLine("x={0}", x); //x=100
    // myInt = x as MyInt; //错误CS0039: 无法通过引用转换、装箱转换、取消装箱转换、包装转换或 Null 类型转换将类型“int”转换为“MyInt”
    object xobj = x; //把x装箱
    myInt = xobj as MyInt; //as不会调用自定义转换
    Console.WriteLine("myInt={0}", (myInt == null ? "null" : myInt.ToString())); //myInt=null
    myInt = (MyInt)xobj; //装箱后这样转换会出异常
    //必须要显式拆箱再转换,如:myInt=(MyInt)(int)xobj;
    Console.WriteLine("myInt={0}", (myInt == null ? "null" : myInt.ToString())); //这一句不会执行
    }
    catch(Exception e)
    {
    Console.Error.WriteLine(e);
    //System.InvalidCastException ...
    }
    }
  • 相关阅读:
    [改善Java代码]养成良好习惯,显式声明UID
    [改善Java代码]警惕自增的陷阱
    [改善Java代码]覆写变长方法也循规蹈矩
    [改善Java代码]别让null值和空值威胁到变长方法
    [改善Java代码]避免带有变长参数的方法重载
    [改善Java代码]三元操作符的类型务必一致
    关于Windows下mysql忘记root密码的解决方法
    关于同步VSS服务器上的代码发生Eclipse里面的项目全部不见了
    关于关闭Eclipse的控制台自动跳出
    关于Windows下如何查看端口占用和杀掉进程
  • 原文地址:https://www.cnblogs.com/pcy0/p/cs_learning_user_cast.html
Copyright © 2020-2023  润新知