本章节主要来讲解关于运算和类型转换的一些问题。
5.1 条件运算符
条件运算符(?:)也成为三元运算符,也就是if..else结构的简化形式。其语法:condition? true_value:false_value下面给出列子来
string s = x + " ";
s += (x == 1 ? "Man" : "Men");
Console.WriteLine(s);
5.2 checked和unchecked运算符
checked运算符主要是可以在编译的时候检查代码中的溢出问题。如下面代码:
checked
{
b++;
}
Console.WriteLine(b.ToString());
当使用unchecked,不会抛出异常,但是会丢失数据。如下代码:
unchecked
{
b++;
}
Console.WriteLine(b.ToString());
运行结果为:0,说明数据已经溢出,数据丢失了,导致结果为0
5.3 is运算符
该运算可以检查对象是否和特定的类型兼容。“兼容”表示对象的是该类型,或者派生于该类型。如下例子:
if (j is object)
{
Console.WriteLine("i is an object");
}
5.4 可空类型和运算符?
对于bool类型,可以指定他为true或者false。但是,要把该类型值定义为undefined,该怎么办。此时可以使用可空类型给应用程序一个独特的值。另外可空类型,通常可以用来读去数据库中的数据,数据库中类型很多都是可空的。下面是个例子
int?a=5;
获取a中的值可以使用a.value,判断是否有值a.hasvalue
5.5 空结合运算符??
int d;
d = c ?? 10;
Console.WriteLine(d.ToString());
c = 3;
d = c ?? 10;
Console.WriteLine(d.ToString());
结果为:10 3
5.6 装箱和拆箱
C#数据类型可以分为在堆栈上分配内存的值类型和在堆上分配内存的引用类型。
装箱是指将值类型转换为引用类型,拆箱是指将引用类型转换成值类型。在使用拆箱和装箱过程中注意转换的类型问题,类型不当,将会抛出异常,如下代码:
long mylong=22222222;
object o=(object)mylong;
int myInt=(int)o;
这样拆箱肯定是会报错的。
主要:装箱和拆箱过程会对性能进行一定损耗的。
5.7 运算符重载
运算符重载就是实现类似数值进行相加、相乘、比较等。例如定义一个类作为矩阵类,让该类实现相加和相乘。这个时候就需要重载运算符了。下面给出一个简单的例子实现3维矢量的重载运算符代码如下
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace VectorDemo
{
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)
{
x = rhs.x;
y = rhs.y;
z = rhs.z;
}
//重载tostring方法
public override string ToString()
{
return "(" + x + "," + y + "," + z + ")";
}
//+运算符重载
public static Vector operator +(Vector lhs,Vector rhs)
{
Vector result = new Vector(lhs);
result.x += rhs.x;
result.y += rhs.y;
result.z += rhs.z;
return result;
}
//* 运算符重载
public static Vector operator *(Vector rhs,double lhs)
{
return new Vector(lhs * rhs.x, lhs * rhs.y, lhs * rhs.z);
}
public static Vector operator *( double lhs,Vector rhs)
{
return new Vector(lhs * rhs.x, lhs * rhs.y, lhs * rhs.z);
}
//*运算符重载
public static double operator *(Vector lhs, Vector rhs)
{
return lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z;
}
//条件运算符必须成对重载
public static bool operator >(Vector lhs,Vector rhs)
{
if (lhs.x>rhs.x)
{
return true;
}
return false;
}
//条件运算符必须成对重载
public static bool operator <(Vector lhs, Vector rhs)
{
if (lhs.x < rhs.x)
{
return true;
}
return false;
}
}
class Program
{
static void Main(string[] args)
{
Vector vect1, vect2, vect3;
vect1 = new Vector(1, 2, 3);
vect2 = new Vector(-1.0, -2.0, -4.0);
vect3 = vect1 + vect2;
Console.WriteLine(vect1.ToString());
Console.WriteLine(vect2.ToString());
Console.WriteLine(vect3.ToString());
vect3 = 2.0*vect2;
Console.WriteLine(vect3.ToString());
}
}
}
注意:重载比较运算符时候必须成对重载。C# 中有三对比较运算符
a.==和!=
b.>和<
c.>=和<=
5.8 用户定义的数据类型转换
C#允许进行两种不同数据类型的转换:隐式(implicit)和显式(explicit)转换
如下demo
int i=3;
long L=i;//隐式(implicit)
short s=(short)i;//显式(explicit)
下面给出个例子,该demo定义了一个currency的结构体。来实现与float的转化
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SimpleCurrency
{
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);
}
//implicit转换
public static implicit operator float (Currency value)
{
return value.Dollars + (value.Cents / 100.0f);
}
//explicit转化
public static explicit operator Currency(float value)
{
checked
{
uint dollars = (uint)value;
ushort cents = Convert.ToUInt16((value - dollars) * 100);
return new Currency(dollars, cents);
}
}
}
class Program
{
static void Main(string[] args)
{
Currency balance = new Currency(100, 50);
float f = balance;
Console.WriteLine(balance.ToString());
Console.WriteLine(f.ToString());
float amount = 56.44f;
Currency amount2 = (Currency)amount;//显式转换
//Currency amount2 = amount;//错误
Console.WriteLine(amount2.ToString());
}
}
}
代码下载: CShrap第五章
小结:本章节就写到这里,下一章节讲详细讲解有关事件和委托问题