2007年8月25日星期六

【c#】C#编程规范


一、命名

1. 用pascal规则来命名方法和类型.

public class TextBox

{

public void DataBind()

{

}

}

2. 用camel规则来命名局部变量和方法的参数.

string userName;

public AddUser(string userId, byte[] password);

3. 所有的成员变量前加前缀 _

public class Database

{

private string _connectionString;

}

4. 接口的名称加前缀 I.

interface ICompare

{

int compare();

}

5. 自定义的属性以Attribute结尾

public class AuthorAttribute : Attribute

{

}

6. 自定义的异常以Exception结尾

public class AppException : Exception

{

}

7. 方法的命名.一般将其命名为动宾短语.

ShowDialog()

CreateFile()

GetPath()

8.代码的缩进.要用Tab,而不要用space.

9. 局部变量的名称要有意义.不要用x,y,z等等(除用于For循环变量中可使用i,j,k,l,m,n).

string userName

10. 所有的成员变量声明在类的顶端,用一个换行把它和方法分开.

11. 用有意义的名字命名namespace,如:产品名、公司名.

12. 建议局部变量在最接近使用它时再声明.

13. 使用某个控件的值时,尽量命名局部变量.

14. 把引用的系统的namespace和自定义或第三方的用一个换行把它们分开.

15. 文件名要能反应类的内容,最好是和类同名,一个文件中一个类或一组关连类.

16. 目录结构中要反应出namespace的层次.

17. 大括号"{"要新起一行.

public class AuthorAttribute : Attribute

{

}

二、编码习惯.

1. 用C#预定义的类名,而不要用别名.

string userName; 而不是 System.String userName;

int number; 而不是 System.Int32;

2. 一行不要超过80个字符.

3. 尽量不要手工更改机器生成的代码,若必须更改,一定要改成和机器生成的代码风格一样.

4. 关键的语句(包括声明关键的变量)必须要写注释.

5. 文字常量和数字常量不要硬编码,应该用常量类或枚举代替.

6. 不准使用goto系列语句.

7. 不要声明public和protected的成员变量,应用property.

8. 不要声明public的event,应用事件访问器.

public class Source

{

private EventHandler m_NumberChangeEvent;

public event EventHandler NumberChangeEvent

{

add

{

m_NumberChangeEvent += value;

}

remove

{

m_NumberChangeEvent -= value;

}

}

}

9. 类型转换的使用规则.

Animal animal = new Dog();

Dog dog = animal as Dog;

if (dog != null)

{

}

10. 生成和构建一个长的字符串时,一定要使用StringBuilder,而不用string.

11. 始终使用"{ }"包含if下的语句,即使只有一条语句.

12.switch 语句一定要有default来处理意外情况.

13. 尽量少使用三目运算符 ? : ,而要使用if语句.

14. 尽量不用使用this引用,除非是要调用类中的另一个Constructor.

public class Person

{

public Person(string name)

{

}

public Person() : this("Jim")

{

}

}

【c#】C#语法入门

C#语法入门

1、大小写区别

2、在C#中的布尔类型为bool,而JAVA为boolean
3、C#有一个不安全模式,在此模式之下可以使用指针
4、有枚举类型
5、代理和索引器
6、运算符重载
7、没有throws关键字

下面开始C#之行。

在开始学习C#之前,先了解下C#语句的特点:

1. C#是区别大小。2. 每一句都以分号结束,不象VB.NET。3. 多个语句通过分号可以写在一行,不过不推荐,因为不清晰。OK,开始了。

先了解下其数据类型:

bool true或false
byte 8位无符号整数
short 16位整数
int 32位整数
long 64位整数
float 32位浮点数
double 64位浮点数
char 16位字符
string 多个16位字符

宽度窄的(即字节数少的)数据类型可以直接赋给较宽的数据类型,并会自动转换为新类型。例:

float a = 9.9f;
int b=4;
a
= b;
//上述把一个整型的4转换成了浮点型.
同样也可以通过强制类型转换将宽类型的缩成窄类型例:
float a = 9.9f;
int b=4;
b
= (int)a;
//注意必须把要转换的类型名称放在圆括号内,并放在其前面
字符串与数值互换:
string a = Convert.ToString(b);
float a = Convert.ToSingle(b);

同样也可以像C语言那样格式化输出:
float a=3.1415926728f;
string b=a.ToString("##.##");

变量与常量声明:

C#中允许一条语句声明同一类型的多个变量
int a,b;
但为了语句清晰推荐将多个声明写成多个语句。
有一点要注意,就是如果在声明数值型变量时没有小数部分,则自动为整数类型,有小数部分的,则自动为double类型,而不是float类型,可通过下面 声明,转换为不同类型:

float a=1.2f ; long b=23L ;

对于常量声明,习惯用大写符号来表示常数,如:

const float PI = 3.1415926 ;

对于字符声明,得用单引号括起来,如:

char a = 'd' ;

还可以这样赋值:

int a = b = c = 2;

虽然方便,但并不推荐,推荐将其拆成三个语句来写,这样结构也清晰。

(注:C#的变量名长度是任意的,可以由数字和大小写字母混合组成,但第一个必须是字母。

关于C#中的转义字符:

\n ------------------------- 换行
\r ------------------------- 回车
\t ------------------------- 制表符
\b ------------------------- 退格
\f ------------------------- 换页
\0 ------------------------- 空符号
\" ------------------------- 双引号
\' -------------------------单引号
\\ -------------------------反斜杠

还有一个较特殊的,就是@号,只要语句前加@号,即表示@号后面的包括有转义符的都按不进行转义运算。

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

还是先看个例子吧,因为自己也有体会,一味地看语句,很无聊 ^_^

using System;
class sample
{
static void Main(string[] args)
{
string hey="希望如我所愿";
Console.WriteLine(
"c# 快速入门,"+hey);
}

}
[dvnews_page]

很头开始分析:using 语句说明程序中要用到C#的代码库,接着是个类名,可以包括有多个类,类中的东西都必须放在大括号中,整个程序以Main函数开始。按F5可以编译执行。 好,完成第一个C#程序。再来看烦燥的语法:

运算符:

算术运算符:

+ --------------------- 加
- --------------------- 减
* --------------------- 乘
/ --------------------- 除
% --------------------- 求余(即整除后的余数)

逻辑运算符:

& --------------------- 按位与
| --------------------- 按位或
^ --------------------- 按位异或
~ --------------------- 取反
>>n ------------------- 右移n位
<<n ------------------- 左移n位

递增递减运算符:

++ 或 -- 或 += 或 -= 或 *= 或/=

如i=1;i++;即等i=i+1; 其它为同样的道理,不说。

比较运算符:
> 或 < 或 == 或 != 或 >= 或<= 一看就明白,也不说。

C#的条件判断:

if(a > 0)
{
a = -1;
}
else
{
Console.WriteLine(a);
}
条件必须放在括号里.

两个条件的判断,注意括号和条件中的等号
if((a = = 0) && (b>0))
{
a = -1;
b = -1;
}
else
{
Console.WriteLine(a + b);
}


switch 用于多个可能的值,如果有一个匹配,则执行相应代码,每句之后必须有break语句中断后面语句的执行。
switch(a)
{
case 1:
Console.WriteLine("1");
break;
case 2:
Console.WriteLine("2");
break;
case 3:
Console.WriteLine("3");
break;
default:
Console.WriteLine("default");
}

while 循环:
-------------------------------------------
a=1;
while (a<20)
{
a=+=a;
}
只要a<20这个条件为真,则循环加a,直到a<20
------------------------------------------
do-while 循环:
------------------------------------------
a=1;
do
{
a=+=a;
}
while(a<20);
------------------------------------------
do while循环与while循环类似,区别在于do-while循环至少执行一次a+=a;

for 循环:
-------------------------------------------
int j=1;
for(int i=0;i<100;i++)
{
j++;
Console.WriteLine("i = "+i+"j = "+j);

}
OK,烦人的基本语法介绍完毕。

【c#】命名空间

.NET框架类库包含了大量用于创建ASP.NET页面的类(三千多个),这些类由命名
空间组成层次结构。
命名空间是类的逻辑分组,它组织成一个层次结构——逻辑树。这个树的根是System。
在ASP.NET页面中,可以默认的使用某些命名空间中包含的类,称做标准的ASP.NET
命名空间。对于其他命名空间,则必须显式地导入。这些默认的命名空间包含
ASP.NET应用程序中最常用的类,如下所示:
System
System.Collections
System.Collections.Specialized
System.Configuration
System.Text
System.Text.RegularExpressions
System.Web
System.Web.Caching
System.Web.Security
System.Web.SessionState
System.Web.UI
System.Web.UI.HTMLControls
System.Web.UI.WebControls


//////////////////////////////////////////////////////////////////////////////////////
命名空间的概念

C#中采用的是单一的全局变量命名空间。在这单一的空间中,如果有两个变量或
函数的名字完全相同,就会出现冲突。当然,你也可以使用不同的名字,但有时我
们并不知道另一个变量也使用完全相同的名字;有时为了程序的方便,必需使用同
一名字。比如你定义了一个变量String user_name, 有可能在你调用的某个库文件
或另外的程序代码中也定义了相同名字的变量,这就会出现冲突。命名空间就是为
解决C#中的变量、函数的命名冲突而服务的。解决的办法就是将你的strTemp变量
定义在一个不同名字的命名空间中。就好像张家有电视机,李家也有同样型号的电
视机,但我们能区分清楚,就是因为他们分属不同的家庭。

当然,我们也可以使用程序开头的using编译指示来使用命名空间中的名字。使用
using编译指示的好处在于在程序中不必显式地使用命名空间限制符来访问变量。


命名空间(Namespace):使用层次模型组织类,其优点是可以防止对象命名上的冲突。

其实,命名空间的使用上类似与VB中的以下结构:

With XXX Do
Begin
MemberA=A
MemberB=B
End;

////////////////////////////////////////////////////////////////////////////////////////////
C#中的类是利用命名空间组织起来的。命名空间提供了一种从逻辑上组织类的方
式,防止命名冲突。
命名空间声明
用namespace 关键字用于声明一个命名空间。此命名空间范围允许您组织代码并为
您提供了创建全局唯一类型的方法。
namespace name
{
类型定义
}
其中:在命名空间中,可以声明类、接口、结构、枚举、委托 命名空间。

如果未显式声明命名空间,则会创建默认命名空间。该默认的命名空间(有时称为
全局命名空间)。全局命名空间中的任何标识符都可用于命名的命名空间中。

命名空间声明可以作为顶级声明出现在编译单元中,当命名空间声明作为顶级声明
出现在编译单元中时,该命名空间成为全局命名空间的一个成员。

命名空间声明出现在另一个命名空间声明内时,该内部命名空间就成为包含着它的
外部命名空间的一个成员。

无论是何种情况,一个命名空间的名称在它所属的命名空间内必须是唯一的。命名
空间隐式地为 public,而且在命名空间的声明中不能包含任何访问修饰符。

嵌套的命名空间
命名空间声明中声明命名空间,各命名空间用"."分隔。
例如:
namespace N1.N2
{
class A {}
class B {}
}
在语义上等效于
namespace N1
{
namespace N2
{
class A {}
class B {}
}
}

引用类
引用一个类可以用完全限定名来限定引用类(类名前加上命名空间名),以防止命名
冲突。
using 指令来导入其他命名空间和类型的名称,直接地而不是通过限定名来引用它们。

Using指令
using 别名指令为一个命名空间或类型启用一个别名。
using 命名空间指令用于导入一个命名空间的类型成员。

(1) using 命名空间指令将一个命名空间中所包含的类型导入到编译单元或命名空
间体中,从而可以直接使用这些被导入的类型的标识符而不必加上它们的限定名。
如:
namespace N1.N2
{
class A {}
}
namespace N3
{
using N1.N2;
class B
{
public static void Main()
{
A a=new A();
}
}
}
上面的示例中,在 N3 命名空间中N1.N2 的类型成员是直接可用的,不需要完全限定名.

(2)using 命名空间指令导入包含在给定命名空间中的类型,但要注意,它不导入
嵌套的命名空间。
示例:
namespace N1.N2
{
class A {}
}
namespace N3
{
using N1;
class B
{
public static void Main()
{
A a=new A(); //错误,N1.N2命名空间中的类型没有导入到命名空间N3中
}
}
}

(3)using 命名空间指令导入的名称会被编译单元或命名空间体中具有相同名称的
成员所隐藏。

例如:
namespace N1.N2
{
class A {}
class B {}
}
namespace N3
{
using N1.N2;
class A {}//N3.A
}
在 N3 命名空间中的A类与N1.N2命名空间中的A类名称相同,则N1.N2.A被N3.A隐
藏,A 引用 N3.A 而不是 N1.N2.A。

(4)同一编译单元或命名空间体中的 using 命名空间指令导入多个命名空间时,如
果它们所包含的类型中有重名的,则直接引用该名称就被认为是不明确的。
示例:
namespace N1
{
class A {}
}
namespace N2
{
class A {}
}
namespace N3
{
using N1;
using N2;
class B
{
public static void Main()
{
A a=new A()// 错误A类明确,要使用完全限定名
}
}
}
N1 和 N2 都包含一个成员 A,而由于 N3 将两者都导入,所以在 N3 中引用 A 会
导致一个编译时错误名称冲突.

using 别名指令用于为一个命名空间或类型指定一个别名。
using 标识符 = 命名空间或类型名称 ;

例如:
namespace N1.N2
{
class A {}
}
namespace N3
{
using A = N1.N2.A;
class B: A {}
}
上面的示例中,在 N3 命名空间中,A 是 N1.N2.A 的别名,因此类 N3.B 从类
N1.N2.A 派生。通过为 N1.N2 创建别名 R 然后引用 R.A 可以得到同样的效果:
namespace N3
{
using R = N1.N2;
class B: R.A {}
}

using 别名指令中的别名在直接包含该 using 别名指令的编译单元或命名空间的
声明空间内必须是唯一的。例如:
namespace N3
{
class A {}
}
namespace N3
{
using A = N1.N2.A; // 错误,命名冲突
}
上例中,N3 已包含了成员 A,因此 using 别名指令使用 A 作标识符会导致一个
编译时错误。

2007年8月20日星期一

初级C#学习笔记(1)

整数类型


最小值

最大值

sbyte

-128

127

byte

0

255

short

-32768

32767

ushort

0

65535

int

-2147483648

2147483647

uint

0

4294967295

long

-9.22 X 1018

9.22 X 1018

ulong

0

1.84 X 1019

* 变量名称前面有"u" 的,是UNSIGNED的缩写,表示这种类型只能存储正数,不能存储负数。

实数类型


最大近似值

最小近似值

decimal

1.0 X 10-28

7.9 X 1028

float

1.5 X 10-45

3.4 X 1038

double

5.0 X 10-324

1.7 X 10308

字符和布尔

char

一个Unicode字 符,存储0~65535之间的整数

string

无上限的一组字符(使用可变大小的内存存储)

bool

true或者false

字面值

类型

类别

后缀

示例/允 许的值

bool

布尔

无

true或flase

int,uint,
long,ulong

整数

无

100

uint,ulong

整数

u 或 U

100U

long,ulong

整数

l 或 L

100L

ulong

整数

ul,uL,Ul,UL,
lu,lU,Lu,LU

100UL

float

实数

f 或 F

1.5F

double

实数

无 或 d 或 D

1.5

decimal

实数

m 或 M

1.5M

char

字符

无

a',或转义序列

string

字符串

无

"a…a",可 以包含转义序列

字符串的字面值(转义序列)

转义序列

产生的字符

字符的Unicode值

\'

单引号

0x0027

\"

双引号

0x0022

\\

反斜杠

0X005C

\0

空

0X0000

\a

警告(产生蜂鸣)

0X0007

\b

退格

0X0008

\f

换页

0X000C

\n

换行

0X000A

\r

回车

0X000D

\t

水平制表符

0X0009

\v

垂直制表符

0X000B

· "This\'s A" 等价于 "This\u0027s A"

· 如果双引号字符串中包括换行等字符,可以在整串字符前加入@字符表示

"C:\\TEMP\\MYDIR\\MYFILE.DOC" 可以写成 @"C:\TEMP\MYDOR\MYFILE.DIC"

变量的4种 声明形式:

int xSize,ySize;

int age=25;

int xSize=4,ySize=5;

int xSize,ySize=5;

字符串运算符

运算符

类别

示例表达式

结果

+

二元

v1=v2+v3;

V1的值是存储在v2与v3中字符串的连接值

数学运算符

运算符

类别

示例表达式

结果

+

二元

v1=v2+v3;

V1的值v2与v3的和

-

二元

v1=v2-v3;

V1的值v2与v3的差

*

二元

v1=v2*v3;

V1的值v2与v3的乘积

/

二元

v1=v2/v3;

V1的值v2除 以v3的值

%

二元

v1=v2%v3;

V1的值v2除 以v3的余数

+

一元

v1=+v2;

V1的值等于v2的 值 *

-

一元

v1=-v2;

V1的值等于v2的 值乘以-1


++

一元

v1=++v2;

V1的值是v2+1,v2递增1

--

一元

v1=--v2;

V1的值是v2-1,v2递减1

++

一元

v1=v2++;

V1的值是v2,v2递增1

--

一元

v1=v2--;

V1的值是v2,v2递减1

· ++ 总是使操作数加1; --总是使操作数减1

· 运算符在操作数前面,则操作数先计算,再赋值;

运算符在操作数后面,则是操作数先赋值,再计算。

赋值运算符

运算符

类别

示例表达式

结果

=

二元

v1=v2;

v1被赋值v2的 值

+=

二元

v1+=v2;

v1被赋值v1与v2的和

-=

二元

v1-=v2;

v1被赋值v1与v2的差

*=

二元

v1*=v2;

v1被赋值v1与v2的乘积

/=

二元

v1/=v2;

v1被赋值v1除 以v2的值

%=

二元

v1%=v2;

v1被赋值v1除 以v2的余数

·*= 也可以用与字符串,同+运算符

布尔逻辑运算

运算符

类别

示例表达式

结果

==

二元

v1=v2==v3;

若v2等 于v3,v1为true,否则v1为false

!=

二元

v1=v2!=v3;

若v2不 等于v3,v1为true,否则v1为false

<

二元

v1=v2<v3;

若v2小 于v3,v1为true,否则v1为false

>

二元

v1=v2>v3;

若v2大 于v3,v1为true,否则v1为false

<=

二元

v1=v2<=v3;

若v2小于或等于v3,v1为true, 否则v1为false

>=

二元

v1=v2>=v3;

若v2大于或等于v3,v1为true, 否则v1为false


!

二元

v1=!v2;

逻辑非,(v1是v2的相反值,取反)

&

二元

v1=v2&v3;

逻辑与,(若v2和v3都为true,v1的值为true,否则为false)

|

二元

v1=v2|v3;

逻辑或,(若v2或v3至少有一个为true,v1的值为true,否则为false)

^

二元

v1=v2^v3;

逻辑异或,(若v2或v3有且只有一个为true,v1的值为true,否则为false)


&&

二元

v1=v2&&v3;

结果同&运算

||

二元

v1=v2||v3;

结果同|运算

·&&和||存在的必要性:

1) 性能比&和|要好,因为&amp;&和||仅检查第一个操作数的值,如果第一个已经为false, 那么&amp;&的结果必然是fasle而 不必检查第二个操作数的值;同理如果第一个已经为true,那么||的结果必然是true。

2) 可以避免一些复杂计算的错误,因为&和|要计算全部的操作数的值。例如:

v1= (v2 !=0 ) & (v3 / v2 > 2);

如果v2的 值为0,则v3/v2将会产生"除0错误",导致整个表达式的错误。

位操作

位1

位2

&结果

|结果

^结果

~(取反位)【位1】 结果

1

1

1

1

0

0

1

0

0

1

1

0

0

1

0

1

1

1

0

0

0

0

0

1

左、右移位操作

运算符

类别

示例表达式

结果

>>

二元

v1=v2>>v3;

把v2的 二进制值向右移动v3位(空出位置补0), 得到v1的值。

int v1,v2=10; v1=v2>>1;

10二进制为1010, 右移1位后为101,结果为5

<<

二元

v1=v2<<v3;

把v2的 二进制值向左移动v3位(空出位置补0), 得到v1的值。

int v1,v2=10; v1=v2>>2;

10二进制为1010, 左移2位后为101000,结果为40

·实际 上,每向左移动一位,该书要乘以2;每向右移动一位,则是操作数除以2并丢掉余数。

布尔赋值运算符

运算符

类别

示例表达式

结果

&=

二元

v1 &= v2;

v1的值是v1与v2逻辑与的结果

|=

二元

v1 |= v2;

v1的值是v1与v2逻辑或的结果

^=

二元

v1 ^= v2;

v1的值是v1与v2逻辑异或的结果


>>=

一元

v1 >>= v2;

把v1的二进制值向右移动v2位,得到v1新值

<<=

一元

v1 <<= v2;

把v1的二进制值向左移动v2位,空出的位补0,得到v1新值

运算符优先级

优先级

运算符

高

|

|

|

|

|

|

低

++,--(用作前缀,如v1= ++v2;),(),+,-(一元),!,~

*,/,%

+,-

<<,>>

<,>,<=,>=

==,!=

&

^

|

&&

||

=,*=,/=,%=,+=,-=,<<=,>>=,&=,^=,|=

++,--(用作后缀,如v1=v2++;)