回 帖 发 新 帖 刷新版面

主题:[原创]C#小技巧

有关建议请投在这里:
http://www.programfan.com/club/showbbs.asp?id=87010

-----------------------------------------------------------------------

我搞C#编程有些时候了,现在把自己学会的一些技巧告诉大家。

这里我们假定你使用的是Visual Studio .net 2003

1.#region...#endregion
这个不要说了,相信很多人都在用(如果还不知道的话自己在一段代码前后加这两句,看看什么效果)

2.@
这个符号干什么用的呢?看看一下两句:
System.Console.WriteLine("C:\\Windows\\Explorer.exe");
System.Console.WriteLine(@"C:\Windows\Explorer.exe");
两句输出完全一样……
明白了吧,@加在字符串常量前面,能让编译器知道你后面的那个常量没有转义字符,也就是说把'\'看作字符而不是转义符号。
另外,@支持两个""内加入换行符,譬如:
string s = @"This
is
an
example.";
由于没有了转义符号,因此要表示"这个字符可以这样写:
string s = @"It's called ""xxx"".";//两个"连写表示一个"字符

3.///
这是XML的注释符号。譬如说我有这个函数定义:
int Function(int a,double b);
在定义前面一行,打上///三个字符,看看发生了什么?
/// <summary>
/// xxx
/// </summary>
/// <params name="a">xxx</params>
/// <params name="b">xxx</params>
/// <returns>xxx</returns>
四个xxx是给你填的。那,这里填了有什么用呢?其实,vs的智能感知就是靠这个工作的。它读取你这里的资料,然后为你提供智能感知信息。目前2003版的vs只有C#支持代码文件内嵌XML哦!

日后可能还有补充。这里先写到这里。防止灌水,锁了~

回复列表 (共6个回复)

沙发

感谢版主加精~~偶还要继续

4.运算符优先级
很多人写了一个稍微复杂一点的式子就一直出错。很有可能是操作符的优先级没有考虑。这里把C#的操作符按照[b]从高到低[/b]的顺序排列下来
---------------------------------------------
1.初级操作符 () x.y f(x) a[x] x++ x-- new typeof sizeof checked unchecked
2.一元操作符 + - | ~ ++x --x (T)x
3.乘除操作符 * / %
4.加减操作符 + -
5.位移操作符 << >>
6.关系操作符 < > <= >= is
7.等于操作符 ==
8.逻辑与  &
9.逻辑异或 ^
10.逻辑或  |
11.条件与  &&
12.条件或  ||
13.条件操作符 ?:
14.赋值操作符 = *= /= %= += -= <<= >>= &= ^= |=
---------------------------------------------
要注意的是,位移操作符是算数操作里面优先级最低的。所以要注意是否要加括号。
最后,提醒一句,如果实在是搞不清楚,你就记着一点,乘除高于加减,其他都包括号,保证没问题哈。

5.ref和out
如果玩过C语言的话,那应该知道函数参数传递有一种引用的方法:void f(int& a)
那么,在C#里面如何实现呢?其实,ref和out两个关键字都可以说明让编译器传递变量的地址。它们的使用方法如下:

函数声明:void f(ref int a, out int b),调用函数:f(ref a,out b);
那么,他们有区别的吧。的确,他们的区别就是ref传递的必须是已经初始化的变量,而out没有这个限制(不过这时候在函数体内必须对out进行初始化,[b]而且传入的变量要声明[/b])。譬如说:
void f(ref System.Windows.Forms.Form a){a=new System.Windows.Forms.Form();...}
pubilc static void Main()
{
   System.Windows.Forms.Form myForm;
   f(ref myForm);//出错!myForm必须初始化使用。把这里的所有ref改成out就不会出错了
}

另外,函数参数只有ref和out不同时编译器把他们看作同一个函数,因此不支持重载。也就是说:
void f(ref int a);
void f(out int a);
会出错的。
最后说一下out的用处。其实根据out的意思我们就能推测,事实上out关键字给了我们一个方法,使函数能返回许多值。传入out的值不必初始化,传出的值在函数内完成初始化并赋值。这是函数返回一个值的绝佳途径啊。

板凳

继续:
6.Console输出控制
用过C的朋友知道,printf可以用类似%5d这类的格式符控制输出。那在C#里面能不能做到这点呢?答案当然是能。
察看MSDN可以发现,Console.Write(string,params obj[])的实现是与Format类有关的,再看Format类,可以发现另一个在.net系统中比较重要的主题:格式化类型。这是一个将非string类型转换为一定格式的string的方法。参考MSDN的格式化类型这个主题我们能够知道.net强大的格式化字符串功能,这里只把常用的一些格式输出介绍一下:
Console.Write("{0,3} - {1}",2,3);    //输出:(不包括引号,下同)"  2 - 3",注意这里是右对齐
Console.Write("{0,-3} - {1}",2,3);    //输出:"2   - 3",大括号内逗号后面的数小于0表示左对齐

3 楼

7.条件判断
翻看MSDN可以发现&和&&都可以用来做条件判断。那他们的区别是什么呢?
看看这个:
bool A(bool v)
{
   Console.WriteLine("A is called.");
   return v;
}
bool B(bool v)
{
   Console.WriteLine("B is called.");
   return v;
}

看看调用 A(false) & B(false) 和 A(false) && B(false) 的区别。可以发现,第一个是A、B均调用而第二个B没有调用。原因就是&&(包括||)是做短路计算,如果第一个条件已经为false(或者在||里面已经是true)则不用计算下面的直接返回false(或true)。知道了这个小技巧对于设计条件判断语句有很大帮助哦~~

4 楼

8.GDI+的初级使用技巧
如果你现在还在使用OnPaint()里面的e.Graphics.DrawXXX进行所有的绘图的话,那速度一定会让你吃不消的。怎么办?呵呵,试试这一招:
Bitmap buffer=new Bitmap(100,100);
System.Drawing.Graphics g=System.Drawing.Graphics.FromImage(buffer);
g.DrawXXX;
e.Graphics.DrawImage(buffer);
怎么样?速度是不是上去了?画面也是不是平滑一些了?
原理很简单,直接操作内存要比一个pixel一个pixel画要快。而且把图像先在内存中操作好然后统一渲染,不会给人画面迟钝的感觉。

5 楼

9.使用unsafe关键字
C#支持使用非托管的指针,语法就如同C++里一样。譬如要设计一个链表:
unsafe class ListNode
{
    protected ListNode* Next;
    ...
}
当然,unsafe可以加在任何类型、函数的声明前面作修饰,甚至还可以这样嵌在代码块里:
public int f(double b)
{
    int a = Convert.ToInt32(b);
    unsafe
    {
        int *p = &a;
        (*p)++;
    }
    return a;
}

当然,带unsafe的代码能正确编译必须要打开/unsafe选项(或者在生成选项里打开不安全代码)

6 楼

10.类型转换
类型转换以下几种常用方式
(type)obj
obj as type
还有如果是系统内置类型的话可以用System.Convert类里面的ToXXX()

这里我要推荐的是obj as type。这三种方法里只有这个不会在类型无法转换的时候抛出异常,取而代之的是返回一个null
当然,Type.Parse也是方法之一。不过我想在这些都会抛出异常的方法里,用as能够避免无谓的异常抛出……毕竟处理异常也是一件挺讨厌的事情哈~

11.程序的暂停
有的时候主线程需要暂停几秒。用for等循环语句来写实在是太浪费CPU了。解决办法是:
System.Threading.Thread.Sleep(x);
x是毫秒数
Sleep这个函数的作用是阻塞当前线程一定时间。所以这个函数也能用在子线程的过程中。

我来回复

您尚未登录,请登录后再回复。点此登录或注册