在C#中使用operator关键字来重载内置运算符
/* * 运算符重载 * + - ! ~ ++ -- 一元操作符只有一个操作数,且可以被重载 * + - * / % 二元操作符带有两个操作数,且可以被重载 * == -= < > <= >= 比较运算符可以被重载 * * 运算符只能采用值参数,不能采用ref或out参数。 * C#要求成对重载运算符,如果重载了==,则也必须重载 !=,否则产生编译错误。 * 同时,比较运算符必须返回bool类型的值,这是与其他运算符的根本区别 * * C#不允许重载=运算符,但如果重载例如+运算符, * 编译器会自动使用+运算符的重载来执行+=运算符操作 * * 运算符重载的其实就是函数重载,首先通过指定的运算表达式 调用对应的运算符函数, * 然后再将运算对象转化为运算符函数的实参,接着根据实参的类型来确定需要 * 调用的函数的重载,这个过程由编译器来完成。 */ class Test24 { public void MyFun() { Test24 t = new Test24(); if (t == null) { Console.WriteLine("t为空"); } else { Console.WriteLine("t不为空"); } } public static bool operator ==(Test24 t1, Test24 t2) { if ((t2 as object) == null) { return (t1 as object) == null; } else { return t2.Equals(t1); } } public static bool operator !=(Test24 t1, Test24 t2) { return !(t1 == t2); } public override int GetHashCode() { return base.GetHashCode(); } public override bool Equals(object obj) { return base.Equals(obj); } }
知识点介绍
拆箱是装箱操作的逆向操作过程,把引用类型的对象转换为对应的值类型的值,从内存中堆栈分配的角度来说,就是把堆中的对象复制到堆栈中。由于System.Object 类型也是所有值类型的基类,所以在装箱的过程中,值类型都可以隐式地转换为 System.Object 类型,并且一般不会存在隐患。但是在拆箱时需要特别注意,若类型处理不当,则会产生异常。下面的示例将演示如何进行拆箱操作,以及如何解决在拆箱操作时遇到的错误。
示例
static void assemble() { Int32 i = 10; object obj = new object(); //装箱操作,通常没有异常 try { obj = i; Console.WriteLine("装箱成功!"); } catch (Exception ex) { Console.WriteLine("装箱失败!"); Console.WriteLine(ex.Message); return; } //拆箱操作,易产生隐患 try { Int64 j = (Int64)obj; Console.WriteLine("拆箱成功!"); } catch (Exception ex) { Console.WriteLine("装箱失败!"); Console.WriteLine("拆箱失败的原因:{0}", ex.Message); } }
输出
装箱成功!
装箱失败!
拆箱失败的原因:Unable to cast object of type 'System.Int32' to type 'System.Int64'.
从运行结果可看到,程序将抛出一个InvalidCastException类型的异常,这个异常的含义是无效类型转换或显式转换引发异常。这说明该异常是因被拆箱对象的最初类型与拆箱时的值类型不一致而产生的,同时也论证了拆箱时的一条原则,被拆箱对象的最初类型与拆箱时的值类型必须一致。
解决办法很简单,就是让拆箱对象的最初类型与拆箱时的值类型保持一致。改正后的关键代码如下∶
//改正后的拆箱代码 try { Int64 j = (Int64)(Int32)obj; Console.WriteLine("拆箱成功!"); } catch (Exception ex) { Console.WriteLine("装箱失败!"); Console.WriteLine("拆箱失败的原因:{0}", ex.Message); }
装箱操作是将值类型隐式地转换为 Object 类型。拆箱操作是指显式地把 Object类型转换为值类型。装箱和拆箱操作会影响系统性能,并且拆箱操作容易产生隐患,所以建议,在可以确定类型的情况下,应该尽可能使用泛型技术来处理,从而避免大量地使用拆箱和装箱操作。