运算符和强制类型转换
当前位置:点晴教程→知识管理交流
→『 技术文档交流 』
本文主要介绍一下C#中的运算符和类型强制转换,主要内容包括
1.C#中的可用运算符 2.处理引用类型和值类型时相等的含义 3.基本数据类型之间的数据转换 4.装箱和开箱技术 5.通过强制转换技术在引用类型之间转换 6.运算符重载 7.自定义类型强制转换 下面详细介绍这7点内容 一、C#中的可用运算符 C#中的运算符跟c语言中的差不多,这里介绍几个特殊的运算符 1.1 check和uncheck运算符 如果把一个代码块标记为checked,CLR就会执行溢出检查,如果发生溢出,就抛出异常。如果要禁止溢出检查,可以把代码标记为unchecked。unchecked是默认值。 //运行下面这段代码,就会抛出异常 byte b=255; checked { b++; } Console.WriteLine(b.ToString()); //运行下面这段代码,则不会抛出异常 byte b=255; unchecked { b++; } Console.WriteLine(b.ToString()); 1.2 is运算符 is运算符可以检查对象是否与特定的类型兼容。 int i = 10; if(i is object) { Console.WriteLine("i is an object"); } 1.3 as运算符 as运算符用于执行引用类型的显示类型转换。如果转换类型与指定的类型兼容,转换成功;如果不兼容,返回null object o1 = "some string"; object o2 = 5; string s1 = o1 as string; //s1="some string" string s2 = o2 as string; //s2=null 1.4 sizeof运算符 使用sizeof运算符可以确定堆栈中值类型需要的长度(单位字节):注意只能在不安全的代码中使用sizeof 例如:sizeof(int) 1.5 type运算符 返回一个表示特定类型的Type对象。 例如:typeof(string)返回表示System.String类型的Type对象。在使用反射动态查找对象信息时,这个运算很有效。 二、类型转换 2.1 隐式转换 只能从较小的整数类型隐式转换为较大的整数类型,不能从较大的整数类型隐式地转换为较小地整数类型。 无符号的变量可以转换为有符号的变量,只要无符号的变量值的大小在有符号的变量的范围之内即可。 例如: byte v1 = 10; byte v2 = 23; long total; total = v1 + v2;//v1、v2均隐式转换为long类型 2.2显示转换 在不能隐式转换的时候,可以显示执行这些转换。格式如下: long val = 3000000000; 所有的显示数据类型转换都可能不安全,在应用程序中应包含处理可能失败的数据类型转换的代码。例如:try/catch等int i = (int)val;//编译不会报错 显示转换有一些限制,值类型只能在数字、char类型和enum类型之间转换。不能直接把Boolean数据类型转换为其他类型,也不能把其他类型转换为Boolean数据类型。 2.3装箱和取消装箱 装箱可以把值类型转换成引用类型(boxing),取消装箱可以把引用类型转换成值类型(unboxing) int i = 20; object o = i; //boxing int j = (int)o; //unboxing 三、对象的相等比较 3.1 引用类型的相等比较 有四种方法: 1)ReferenceEquals()方法 ReferenceEquals()方法是一个静态方法,不能重写,只能使用System.object实现。如果提供的两个引用指向同一个对象实例,ReferenceEquals()方法 返回true,否则返回false。但是该方法认为null等于null。 SomeClass x,y; x = new SomeClass(); y = new SomeClass(); bool B1 = ReferenceEquals(null,null);// return true; bool B2 = ReferenceEquals(null,x);// return false; bool B3 = ReferenceEquals(x,y);// return false because x and y point to different objects; 2)虚拟的Equals()方法 Equals()方法是虚拟的,所以可以在自己的类中重写。 3)静态的Equals()方法 静态的Equals()方法和虚拟的Equals()方法作用相同,区别是静态版本带有两个参数。静态方法可以处理两个对象中有一个是null的情况。 4)比较运算符== ==可以看作是严格值比较和严格引用比较之间的中间选项,使用时最好重写==运算符 3.2 值类型的相等比较 值类型的相等比较与引用类型的相等比较采用相同的规则,最大的区别就是值类型需要装箱,才能执行上面介绍的四种方法。 四、运算符重载 4.1 算术运算符重载 例如: //定义结构Vector 注意:C#不允许重载=运算符,但如果重载+运算符,编译器就会自动使用+运算符的重载来执行+=运算符的操作。-=、&=、*=、/=也遵循此规则struct Vector { public double x,y,z; public Vector(double x,double y,double z) { this.x = x; this.y = y; this.z = z; } public Vector(Vector rhs) { this.x = rhs.x; this.y = rhs.y; this.z = rhs.z; } public override string ToString() { return "(" + x + "," + y + "," + z + ")"; } //重载+运算符 public static Vector operator + (Vector lhs, Vector rhs)//C#要求所有的运算符重载都声明为public和static { Vector result = new Vector(lhs); result.x += rhs.x; result.y += rhs.y; result.z += rhs.z; return result; } } //测试 static Main() { Vector vect1,vect2,vect3; vect1 = new Vector(3.0,3.0,1.0); vect2 = new Vector(2.0,-4.0,-4.0); vect3 = vect1 + vect2; Console.WriteLine("vect1=" + vect1.ToString()); Console.WriteLine("vect2=" + vect2.ToString()); Console.WriteLine("vect3=" + vect3.ToString()); } //编译运行,结果如下: vect1=(3,3,1) vect2=(2,-4,-4) vect3=(5,-1,-3) 4.2 比较运算符重载 1)C#要求成对重载比较运算符(==和!=、>和<、>=和<=共3对),如果不成对重载,编译就会出错。 2)必须返回bool类型的值。 注意:重载==和!=时,还应重载System.object的Equals()方法和GetHashCode()方法,否则产生一个编译警告。因为Equals()方法执行与==相同的相等逻辑。 除此之外,比较运算符重载跟算术运算符的重载没有区别。 五、用户定义的数据类型转换 用户定义的数据类型转换和预定义的数据类型转换一样,也分隐式转换和显示转换两种。 如果知道无论在源变量中存储什么值,数据类型转换总是安全的,就可以用隐式转换; 如果某些数据值可能会出错,就应该把数据类型转换定义为显示的。 定义数据类型的转换类似于运算符重载: public static implicit operator float(Currency value) 执行用户类型转换的完整示例:{ //processing } 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 operator float(Currency value) { return value.Dollars + (value.Cents/100.0f ); //显示转换 public static operator Currency(float value) { uint dollars = (uint)value; ushort cents = (ushort)((value-dollars)*100); return new Currency(dollars,cents); } } } //测试 static Main() { 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); } //结果 50.35 balance is $50.35 balance is (using ToString()) $50.35 After converting to float,50.35 After converting back to currency,$50.34" 5.1 类之间的数据类型转换 两个限制: 1)如果某个类直接或间接继承了另一个类,就不能在这两个类之间进行数据类型转换。 2)数据类型转换必须在源或者目标数据类型定义的内部定义。 5.2 基类和派生类之间的数据转换 //类MyDerived派生于类MyBase MyDerived derivedObject = new MyDerived(); MyBase baseCopy = derivedObject;//隐式转换 MyBase baseObject = new MyBase(); MyDerived derivedCopy = (Myderived)baseObject;//抛出异常 5.3 装箱和取消装箱数据类型转换 值类型到object的转换是隐式转换 ,即装箱 Curency banlance = new Currency(40,10); object到值类型的转换是显示转换,即取消装箱object baseCopy = banlance;//隐式转换 object derivedObject = new Currency(40,10); object baseObject = new object(); Currency derivedCopy1 = (Currency)derivedObject;//OK Currency derivedCopy2 = (Currency)baseObject;//抛出异常 5.4 多重数据类型转换 Currency balance = new Currency(40,10); long amount = (long)balance;//Currency->float->long double amountD = balance;//Currency->float->double 该文章在 2017/2/7 18:51:16 编辑过 |
关键字查询
相关文章
正在查询... |