搞一搞C#,发现有些语法比较怪,要是不怎么用会忘得,留个纪念here。东西大多来自Csharp 高级编程,当然这只是一小部分
类和struct区别
对我来说最大的区别是实例化的方式,类肯定是在heap上的,都用new.
而struct可就猛了,可以是stack也可以是heap(说实话本来挺好个东西用起来反倒比较恶心,struct规则太搞,在加上.net中装箱拆箱这个东东的存在,害得我兴趣,编程中避免使用)
is运算符
is运算符可以检查对象是否与特定的类型兼容。例如,要检查变量是否与object类型兼容:
注意:
“兼容”是指对象是该类型,或者派生于该类型。
int i = 10;
if (i is object)
{
Console.WriteLine("i is an object");
}
int和从object继承而来的其他C#数据类型一样,表达式i is object将得到true,并显示信息。
a s运算符
as运算符用于执行引用类型的显式类型转换。如果要转换的类型与指定的类型兼容,转换就会成功进行;如果类型不兼容,as运算符就会返回值null。如下面的代码所示,如果object引用不指向string实例,把object引用转换为string就会返回null:
object o1 = "Some String";
object o2 = 5;
string s1 = o1 as string; //s1 = "Some String"
string s2 = o2 as string; //s1 = null
as运算符允许在一步中进行安全的类型转换,不需要先使用is运算符测试类型,再执行 转换。
Checked关键字
检测是否有越界的情况,有的话会抛异常,用法
checked{ yourcode; }
另一种情况用来检测类型转换的
long val = 3000000000;
int i = checked((int)val);
装箱和拆箱的危险
装箱拆箱本身很简单,除了网上到处讨论的潜在的性能问题和有时候存在的改变副本那种情况外。这里说说简单的情况,装箱的是什么类型,拆箱也一定要用特定类型,不然会有InvaildCastException,如下代码
int itest = 5;
object o = itest;
long lo = (long)o;
ReferenceEquals()方法
object的静态方法,所以在哪都能用,用来判断两个引用是否引用同一个实例。(听起来像cpp的指针比较一样,其实不一样,.net中这个引用指向的地址会变来变去,oh shit,如果你搞C++/CLI就懂传统指针与这个交互是多么恶心了)
代码
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
还有一点,这个东西不能比较值类型,装箱后的东东肯定放在不同地方,所以总false。
那些操作符可以重载
类 别 运 算 符 限 制
算术二元运算符 +, *, /, –, % 无
算术一元运算符 +, –, ++, –– 无
按位二元运算符 &, |, ^, <<, >> 无
按位一元运算符 !, ~, true, false true和false运算符必须成对重载
比较运算符 ==, !=, >=, <, <=, > 必须成对重载
赋值运算符 +=,–=,*=,/=,>>=,<<=,%=
,&=,|=,^= 不能显式重载这些运算符,在重写单个运算符如+,–,%等时,它们会被隐式重写
还有[]和()
看看重载()
public static implicit operator float (Currency value)
{
// processing
}
上面代码是实现如下功能
Currency c;
//....
fload f = c;
其中implicit表示可以隐式转换
explicit 关键字表示显示转换,oh yeah.
定义类类型的转换时会发生什么呢?你可以搞死编译器
public static explicit operator D(C value)
{
// and so on
}
public static explicit operator C(D value)
{
// and so on
}
这是大大的不允许地。