前言:年关将至,因此到处都出现了各种各样的总结和归类文章。因此,这里我也带各位读者对.NET中出现的符号总结一下,温故知新,希望能将你可能对有些符号的模糊的记忆重新理清,对你有所启示。

    程序员们,花5秒钟将你的眼神从屏幕上挪开,看下你的键盘(e.g.图1),找找键盘上那些熟悉的符号,作为一个C#开发人员,你有没有突然发现它们大部分都是那么的亲切呢?是的,看看键盘上的这些符号,大部分都已经被微软用掉了,剩下的几个虽然目前没被用上,但我相信微软内部应该也有人盯着他们,指不定哪天你就会发现一个新的符号用法会加入到C#中来。因为符号在一门语言中往往比字母更能形象的传文达意,同时给开发人员留下深刻的印象,最常见的例子就是+/-/*//这些数学操作符了,而且相对java来讲,.net还支持用户重载常用操作符。言归正传,下面我将按键盘布局从左往右一一讲解这些符号,顺便也带大家复习下这些符号。

x200-keyboard

                                              图1,键盘符号图

单个符号

   由于在C#中这些符号不仅单用,还有各种组合使用情况,因此这里首先介绍它们但用的情况。

1. ~

    首先是按位求补符。这个符号可能有些同学见得比较少,不过它确实很有用。e.g. 1的32位表示为0000 0000 0000 0000 0000 0000 0000 0001,那么int a=~1实际为-2,即1111 1111 1111 1111 1111 1111 1111 1110。另外,~在List的BinarySearch中将会使你的操作方便很多。在这个二分查找的实现中,如果查找的元素不在集合中,它会返回一个负值,技巧就在这里,这个数的求补结果是下一个比查找元素大的元素的位置,如果没有更大的元素,那么它表示元素总数。这个技巧使得我们在插入新的元素的时候方便很多。e.g.

代码
static void main()
{
List
<string> list = new List<string>();
int search;

list.Add(
"public");
list.Add(
"protected");
list.Add(
"private");
list.Sort();
search
= list.BinarySearch("protected internal");
if (search < 0)
{
list.Insert(
~search, "protected internal");
}
foreach (string accessModifier in list)
{
Console.WriteLine(accessModifier);
}
}

输出结果为:

private 
protected
protected internal
public

另外一个我们现在用得越来越少的就是析构函数中了,在构造函数前面添加~即可,它相当于告诉CLR你在对象注销时需要释放的操作。关于析构函数有下面需要注意的几点:

  • 不能在结构中定义析构函数。只能对类使用析构函数。

  • 一个类只能有一个析构函数。

  • 无法继承或重载析构函数。

  • 无法调用析构函数。它们是被自动调用的。

  • 析构函数既没有修饰符,也没有参数。

下面给出一个简单的使用例子:
class Car
{
~ Car() // destructor
{
// 添加资源释放操作代码
}
}

不过通常建议是尽量少用析构函数,而以IDispose接口实现来释放资源。

2. !,@,#和$

   !相信地球人都知道,非逻辑运算符,这里不多讲。@常用在字符串开头,它可以告诉编译器忽略转义符,从而可以很方便的将一些特殊字符按用户表达意愿输出,另外在Aspx.Net中这个字符常和其他字符混合使用。#和$微软暂时没盯上(表述错误,后面有补充)。不过$符号相信很多人都熟悉,大名鼎鼎的JQuery使得这个符号处处可见,不过不保证以后微软也插上一脚。

4.%,^,&,*,(),-,+,=,{},|和\

     这些符号基本都是常见符号符号,因此这里也只做简单解释。%是求余运算符,^是异或位运算符,&则是且位运算符,另外|是或位运算符。*既可以用作乘法符号,还可以表示为指针。()和{}用于对象中,前者一方面表示函数参数区域,另一方面在强制类型转换时表示把一种类型强制转换为括号中的类型,除此,它还用来包裹运算部分从而制定运算优先级,后者则长表示代码片段作用域,它既可以用于指代命名空间中的有哪些类或类中包括哪些属性方法等,还可以用于在协助C#中某些特殊操作时指定其作用块,如fixed,using等等,另外在字符串格式化中,{}和数字组合表示目标字符串中待替换子串位置, e.g. String.Format(“{0} + {1}={3}”, 1,2,3)。+通常表示相加数学运算符,=则长用来表示赋值操作。另外,这些操作符可以组合来表示不同含义,后面将会详细说明这一部分。\用于转义符的开始,如\n表示换行。

5.[]

   这个符号同样常见,它通常有三种使用方式,一个是用于数组中表示索引位置,一种为添加类型的特性时使用,另外它也常常和this关键字在类中配合使用来形成类索引。e.g.

class Some
{
int this[string item]
{
get
{
if(item==”a”)return 1;
return 0;
}
}
}

6. :,;',”,’,<,,,>,.,/,?

  :目前没有单独使用情况,后面会讲到它的组合使用,;处处可见,C#不像VB,它用;表示语句的结束。”包裹字符串,’则包裹单个字符。<和>分别为大和小的逻辑运算符,,用于分隔参数,.用于表示对象成员选择器或小数点。/则表示除以的数学运算符。?单个常用于表示可空的值类型,e.g. int? a=null,它也可以与很多字符组合使用来表示不同意义。

符号组合

  好了,键盘上的符号键基本介绍完毕,在C#中,符号更为强大的一面是它们之间不同组合产生不同的意义,这里将会对此作出一些简单介绍。

1. 单个字符重复组合

   这里有?和+,-,&,|,<,>以及=。??同样用于泛型中,它在值类型数据操作时非常有用,它可以在值类型为空时指定默认值,e.g. int a=someNullable??100;它表示如果someNullable不为空时则将其值赋给a,否则将100赋值给a,另外你也可以参考这篇文章。++和--表示自加或减1。&&,||和==则表示逻辑关系的且,或和相等。<<和>>则分别表示左右移位操作。最后//表示单行注释,O(∩_∩)O~。

1. 数学运算符,位运算符,逻辑运算符和=的组合使用。

    和C/C++中类似,C#通过这两种符号的组合简化了程序员在常见数学运算时的输入。如+=,-=,*=,/=,%=,还有&=,~=,|=等,它是一个数自身与某个数做相应数学操作的结果。如a+=10完整形式为:a=a+10。逻辑运算符和=则表示或的关系,如>=表示大于或等于。

2. ?和:组合

  这个组合的符号不是紧挨着的,不过他们必须组合使用。这里?和:组成条件表达式,e.g. int c= a==b?a:b; 它的存在同样简化程序员代码。

3. =>组合以及<>配对

   =>组合是3.0以后加入的,它也是构成Lamda表达使得部分,它使得匿名函数的书写更加简洁。通常它前面会包含有表达式参数部分,后面则是表达式的主体部分。<>则在泛型中大量使用,它用来包裹类型参数。

4. ASPX页面中的符号组合

    在ASPX中组合符号很多,一般基本都是左右尖括号和其他符号组合来表示服务器端脚本代码,从而达到插入服务器代码的目的。这里仅列出一些常见符号组合。

      首先<%@ 和%>用来表示ASPX 2.0的Page指令,它一般出现在页面顶部。在ASPX.NET页面或用户控件中有11个指令(注1),指令格式为:<%@ [Directive] [Attribute=Value] %>。

      <%=%>用于在HTML代码中插入.NET代码片段。在Aspx.Net MVC中这个字符组合非常常见,这点类似以前的ASP,这也是有些程序员认为MVC退回到ASP时代的一个原因。

总结

     符号在很多时候不仅比字符更加简洁的表达意思,而且它还更形象和直观,这也是符号在.net中出现的一个原因。不过符号并不是越多越好,所谓过犹不及,太多太复杂的符号有时候反而会让程序员产生混淆和误解。所以目前.NET中出现的符号数量并不是太多,并且未来.NET中符号应该是基本固定的。不过这并不妨碍微软在适当的时候添加一些新的,有用的符号。比如有人在展望.NET 5.0的时候曾提到目前微软推出的Vedea语言的一个很不错的特性:绑定,它的符号为:textbox.Text := slider.Value; 这意味着当Value改变的时候,Text也会相应改变。而双向绑定的语法则有所不同:textbox.Text :=: slider.Value; 相信这个新的符号如果加入到.NET中来一定会让我们的代码比以前更加方便的!同时也期待类似的能简化我们程序员并且形象,直观的新特性符号能在未来出现。对了,你又期待有怎样的新符号加入呢?

附:

    非常谢谢Arthas-Cui补充的总结的更多关于C#的符号用法,这里我把它们补充上来吧。

    1,@

        有些时候我们可能需要用到一些.net里面的关键字同名的变量来更准确的表达变量的含义,但关键字做变量在C#中是不被允许的,这个时候@就可以派上用场了。e.g.

public static void SomeMethod(this Form @this)
{
string a=@this.Text;
}

       这里@this变量你用Reflector查看IL变量的话会发现它变成了this了,不过它在编译器中还是被认作@this。如果有时候我们确实需要这种场景的话它会对你的代码有所帮助。

    2,#

        有时候我们在处理了常见的异常之后最后可能会经常补充一个catch来捕获所有其他未处理的异常信息,但这个catch可能并没有写上exception变量,e.g.catch{// 异常处理程序}。那么如何获取exception信息呢。这时候只要在即时窗口或者监视窗口输入:$exception就可以了。

        关于#一个很常见并且很常用的场景Arthas-Cui也补充了,划分代码块和条件编译。e.g. 

#if
#else
#define
#region
#endregion
   3,$

       $符号在匿名方法时候编译器会偷偷用到,这个我们可以通过查看IL代码了解它的命名。不过这个方法对程序员是不可见的。机器产生的私有方法并不显示在 IntelliSense 中,也不能显式地调用它。

  

注1:Asp.Net中的11页面或用户控件指令为:Assembly, Control, Implements, Import, Master, MasterType, OutputCache, Page, PreviousPageType, Reference, Register.

posted on 2009-12-25 09:06  jujusharp  阅读(3464)  评论(17编辑  收藏  举报