C#语言基础

C#语言基础

一、C#语法基础

.NET概述

.NET是基于Windows平台的一种技术。包含了能在.NET Framework平台运行的所有编程语言。它包含了一个庞大的代码库,各种能运行在.NET Framework平台上的语言都可以共享这个代码库。

认识C#程序

C#(发音为 C Sharp)是一门完全面向对象的语言,也是Microsoft.NET平台运行的主流语言。

书写规范:C#中大括号"{“和”}"各占据新的一行

以下为一个普通的C#程序示例:

using System;

namespace HelloWorld
{
    class Program
    {
        static void Main(string [] args)
        {
            Console.WriteLine("Hello World");
            Console.ReadLine();
		}
    }
}

以上代码的组成部分 一 一 说明:

1.namespace关键字

namespace(命名空间)是C#中组织代码的方式,它的作用类似于Java中的package(包),可以大大的提高管理和使用效率。

2.using关键字

在C#中,使用using关键字来引用其他命名空间,它的作用和Java中的import类似

3.class关键字

C#是一门完全面向对象的语言,使用class关键字表示类。编写的代码都应该包含在一个类中,类要包含在一个命名空间中

4.Main()方法

C#中的Main()方法与Java中的一样,都是程序运行的入口。但要注意的是,C#中的Main()方法首字母必须大写,方法的返回值可以是void或者int类型,Main()可以没有命令行参数。

语法有四种

static void Main(string [] args){}
static int Main(string [] args){}
static void Main(){}
static int  Main(){}

以上都是C#中的Main()方法语法。

5.关键代码

Main()方法中添加的两行代码就是这个小程序的关键代码,用于输出和输入

Console.WriteLine();   //从控制台输出内容  输出后换行
Console.Write();       //从控制台输出内容  输出后不换行
Console.ReadLine();    //从控制台输入内容

C#中的变量和常量

C#中的数据类型
常用的数据类型JavaC#举例
整型intint年龄
浮点型floatfloat成绩
双精度型doubledouble圆周率
字符串型Stringstring姓名
布尔型booleanbool是否正确

C#中的布尔型关键字与Java不同,使用的是bool,C#中字符串型的关键字首字母是小写的

当然C#中的数据类型也不止这些,也包括Java中的基本数据类型,引用数据类型。

需要注意的是数组与Java中有所不同

声明不同。Java有两种方式,而C#只有一种,如下:

数据类型 [] 数组名;

赋值不同,Java中不能赋值的同时给长度,而C#可以:

数据类型 [] 数组名 = new 数据类型[长度]{值};

但是长度必须与值的个数一致

C#中的变量

C#中的变量声明方式使用的语法为

数据类型 变量名称;

C#中的变量命名规则与Java基本相同,有两点不同:1.不能包含“$”符号,2.不能以数字开头。

总结变量命名规则

1、以字母、数字、" _ " 组成,除此之外不能包含其他任意字符。

2、只能以字母和 " _ " 开头。

3、不能使用C#中的关键字,不能包含任意特殊字符。

4、使用驼峰命名法命名,即第一个单词首字母小写,其他单词首字母大写。

C#中的常量

用于在程序中一旦设定就不允许被修改的值,语法:

const 数据类型 常量名 = 值;

需要使用const关键字修饰。

如何使用:用于程序中被经常引用的值、用于程序中具有特定含义的值。

C#中的Console类

C#向控制台输出

有三种方法:

Console.WriteLine();  
Console.WriteLine(要输出的值); 
Console.WriteLine("格式字符串",变量列表);  

第三中方式中,WriteLine()的参数由两部分组成:格式字符串和变量列表。在格式字符串中,依次使用{0}、{1}、{2}···代表要输出的变量,{0}这些表示占位符,将变量依次排列在变量列表中,{0}表示变量列表第一个变量,{1}表示变量列表的第二个变量,以此类推。

C#向控制台输入

语法:Console.ReadLine();

该语法只是用于往控制台输入字符串类型,但是需要输入其他类型时就需要类型转换了:

类型转换

1、隐式:自动转换

​ 在类中当一个数据类型比另一个大时(包含),就可以自动转换,例如

int b = 1;
long a = b;

2、强转

有两种:

1、数据类型.Parse(String);

这种类型只是用于string类型转换为其他类型,不接受其他数据类型作为参数。

2、Convert.To数据类型(任意数据类型)

Convert类可以在各种基本类型之间执行数据类型的互相转换。Convert类为每种类型转换都提供了一个对应的方法,如下表所示:

方法说明
Convert.ToInt32()转换为整型(int 型)
Convert.ToSingle()转换为单精度浮点型(float 型)
Convert.ToDouble()转换为双精度浮点型(float 型)
Convert.ToString()转换为字符串类型(string 型)

这些方法中的参数就是需要转换的数据

类和对象

C#中类的成员分为三个:字段、属性、方法。

字段通常是私有的。如果要访问类中的字段,需要通过get和set访问器实现,这种结合了字段和方法的实现方式称之为属性。

类的三大特性:封装、继承、多态。这里主要说封装。

自定义方法

[访问修饰符] 返回值类型 方法名 (参数列表)
{
	//方法的主体
}

访问修饰符:

private(私有的): 只有当前类能访问
protected(受保护的): 只有当前项目能访问
public(公开的): 不受限制。任何类都可以访问
internal(默认的): 与受保护的相同

方法的返回值类型:可以是基本数据类型的 如果不需要返回值需要使用void关键字。

方法名:每个自定义的方法都有一个方法名。命名方式使用帕斯卡命名法,即每个单词首字母大写。

参数列表:调用方法时,可以向方法中传递参数,这些参数构成了参数列表。

方法主体:方法主体就是这个方法实现某一特定功能的代码。

C#属性

1.用方法保证数据安全

2.用属性实现字段封装:

封装是将数据和操作方法保存在一起的技术,或者有选择的隐藏或公开类中的属性和方法。

private string name;
public string name
{
	get{return name;}   //只读
	set{name=value;}	//赋值(只写属性)
}

get:用来返回相应的私有字段的值,必须有return。

set:用来设定相应的私有字段的值。需要赋值。

this关键字

使用this关键字可以解决成员变量和局部变量名称的冲突问题。

this是当前类的引用,不能在静态成员中引用。

this关键字代表的是当前的对象,在类的内部,可以用this关键字访问类的成员。

值传递和引用传递

当方法为有参方法时,就需要传递参数,这里就涉及到了实参与形参之间的相互影响。

值传递:分为基本数据类型和引用数据类型:

​ 基本数据类型:形参所作修改不会影响实参。

​ 引用数据类型:形参如果修改具体的值会影响实参。修改的是地址对实参没有影响。

引用传递: 无论是形参还是实参所作修改都会受影响。实参与形参都需要ref关键字。

public void 方法名(ref 参数1,ref 参数2,···)   //形参
{
	......
}
this.方法名(ref 参数1,···)                     //实参
//以上形参所做改变无论如何都会影响实参。

二、C#中的结构类型

1、顺序结构

就是程序按照顺序,自上而下每一句代码都会执行。

2、选择结构

与Java结构中相同,只有满足某个条件才会执行该代码块,否则不执行。

if结构

语法:

if(条件表达式)
{
	//代码块
}
if-else结构

语法:

if(条件表达式)
{
	//代码块1
}
else
{
    //代码块2
}
多重if结构

语法:

if(条件表达式1)
{
	//代码块1
}
else if(条件表达式2)
{
    //代码块2
}
else 
{
    //代码块3
}
嵌套if结构

语法:

if(条件表达式1)
{
     if(条件表达式2)
    {
        //代码块1
    }
    else
    {
        //代码块2
    }
}
else
{
    //代码块3
}

if结构书写代码规范

1、为了使if结构更加清晰,应该把每个if或else包含的语句都用大括号括起来

2、相匹配的一队if和else应该左对齐

3、内层的if结构相对于外层的if结构要有一定的缩进

switch选择结构

C#的switch结构与Java略有不同,C#要求每个case和default语句中都必须要有break语句,除非两个case中间没有其他语句,那么前一个case可以不包括break,C#中的判断更加灵活,判断的表达式或变量可以是字符串类型,语法如下:

			Java										C#
switch(表达式)									switch(表达式)									
{											  {
    case 常量表达式1:								case 常量表达式1:
    //语句1;										  //语句1;
    	break;/*可以没有*/								 break;//必须有
     case 常量表达式2:								case 常量表达式2:
    //语句2;										  //语句2;
    	break;/*可以没有*/								 break;//必须有
    ······											······
    default:										default:
    //语句n;										  //语句n;
    	break;/*可以没有*/								 break;//必须有
}											  }

注意:

switch 结构中case子句的摆放是没有顺序的,可以把default子句放在最前面,但要注意任何两个case语句不能具有相同的值。case子句中的值必须是常量表达式,不允许使用变量。

3、循环结构

与Java结构中相同,只有满足条件才会循环。

while循环

语法:

while(条件表达式)        //先判断条件是否满足,如果条件成立就执行循环体
{
	//代码块
}			
do-while循环

语法:

do                        //先执行再判断条件,至少执行一次
{
    //代码块
}while(条件表达式);	
for循环

语法:

for(表达式1;表达式2,表达式3)
{
    //代码块
}	

与Java中的相同,可以去我之前写的博客参考一下。

foreach循环

语法:

foreach(元素类型 元素变量名 in 数组)
{
    //代码块
}

在语法中,元素类型值的就是数据类型,“元素”是一个只读变量。

each是每个的意思,foreach循环结构用于遍历一个数据集合的每一项。

注意:foreach结构不能改变数组中各元素的值;如果需要改变数组中元素的值,应该使用for循环。

循环的区别:

while循环:先判断条件是否成立,若条件成立,则执行循环条件。

do—while循环:循环体先执行一次,再判断条件是否成立。

for循环:必须使用整型变量做循环变量计算器。

foreach循环:用于遍历给定数组的所有值。

跳转语句

与java里的相同,在C#中的跳转语句也是一样的。

break

除了在switch结构中使用break退出整个case语句外,也可以用于while,do—while循环等,break语句将程序跳出当前循环结构,并继续执行该循环体后面的语句。

continue

与break语句类似,continue的作用与Java是相同的即跳出本次循环进入下一轮循环。

冒泡排序

冒泡排序就像它的名称一样,冒泡排序是从底层的元素开始,比较它和它上方紧挨着的元素,如果下面的元素小于上面的元素,就交换它的位置,否则保持原样,如此重复下去,直到所有的元素按从小到大的顺序排列。使用二重循环来排列。内层循环控制循环条件,外层循环控制次数。

冒泡排序速记(升序):

1.N个数字来排队,两两相比小靠前。

2.外层循环N-1,内层循环N-1-I。

3.如果要降序排列,只要把程序中的大于号换成小于号。

三、深入了解string类

常用的字符串处理方法

方法说明
string Trim()去掉字符串前后两端多余的空格
bool Equals(string value)比较一个字符串与另一个字符串value的值是否相等,若两者相等,返回true否则 返回false
int IndexOf(string value)获取value在当前字符串中出现的首个位置
int lastIndexOf(string value)获取指定的字符串value在当前字符串中最后一个匹配的位置
string Substring(int sta)从指定位置sta开始检索长度为length的字符串
string ToUpper()获得字符串大写的形式
string ToLower()获得字符串的小写形式
string []Split(char separator)用指定的分隔符separator分割字符串,返回分割后字符串的数组
int Compare(string A,strin g B)比较两个字符串的大小关系,返回一个整数。若前者大,返回值大于0,反正则小于0,相等就返回0

注意:比较“==”和“Equals()”方法:

运算符""和“Equals()”应用于两个字符串,所判断的内容是有区别的,简单来说”“判断的是两个字符串对象在内存中的首地址,即判断是否是同一个对象。

“Equals()”方法判断的是两个字符串对象的值是否相等。

连接和分割字符串

两种方法 Join()和Split()方法。

//输入提示
Console.WriteLine("请输入一个字符串");
string input=Console.Readine();

//以空格作为分隔符分割字符串
a=input.Split(' ');

//将分割后的字符串使用下划线连接
b=input.Join("-",input);

Format格式化

C#的string类提供的一个Format()方法对输出的字符串进行格式化,Format()方法允许把字符串,数字或布尔类型变量插到格式化字符中。语法如下

String myString =String.Format("格式化字符串",参数列表);

{索引 [,对齐] [: 格式字符串]}

例如:

String myString =String.Format("{0} 乘以 {1} 等于 {2}",2,3,2*3);
//输出2*3=6;

​ 格式化数值结果表

字符说明示例输出
C货币形式String.Format("{0:C3}",2000)¥2000.00
D十进制形式String.Format("{0:D3}",2000)2000
F小数点后的位数固定String.Format("{0:F3}",2000)2000.000
N用逗号(,)隔开的数字String.Format("{0:N}",25000)250.000
P百分比计数字String.Format("{0:P3}",0.29768)29.768
X十六进制格式String.Format("{0:X000}",12)C

C#中的字符串与Java中的相差无几。只是多了几个方法,并无大碍。

1. 避免将多个类放在一个文件里面。 2. 一个文件应该只有一个命名空间,避免将多个命名空间放在同一个文件里面。 3. 一个文件最好不要超过500行的代码(不包括机器产生的代码)。 4. 一个方法的代码长度最好不要超过25行。 5. 避免方法有超过5个参数的情况。使用结构来传递多个参数。 6. 每行代码不要超过80个字符。 7. 不要手工的修改机器产生的代码。 a) 如果需要编辑机器产生的代码,编辑格式和风格要符合该编码标准。 b) Use partial classes whenever possible to factor out the maintained portions. 8. 避免利用注释解释显而易见的代码。 a) 代码应该可以自解释。好的代码由可读的变量和方法命名因此不需要注释。 9. Document only operational assumptions, algorithm insights and so on. 10. 避免使用方法级的文档。 a) 使用扩展的API文档说明之。 b) 只有在该方法需要被其他的开发者使用的时候才使用方法级的注释。(在C#就是///) 11. 不要硬编码数字的值,总是使用构造函数设定其值。 12. 只有是自然结构才能直接使用const,比如一个星期的天数。 13. 避免在只读的变量上使用const。如果想实现只读,可以直接使用readonly。 public class MyClass { public readonly int Number; public MyClass(int someValue) { Number = someValue; } public const int DaysInWeek = 7; } 14. 每个假设必须使用Assert检查 a) 平均每15行要有一次检查(Assert) using System.Diagnostics; object GetObject() {…} object obj = GetObject(); Debug.Assert(obj != null); 15. 代码的每一行都应该通过白盒方式的测试。 16. 只抛出已经显示处理的异常。 17. 在捕获(catch)语句的抛出异常子句(throw),总是抛出原始异常维护原始错误的堆栈分配。 catch(Exception exception) { MessageBox.Show(exception.Message); throw ; //和throw exception一样。 } 18. 避免方法的返回值是错误代码。 19. 尽量避免定义自定义异常类。 20. 当需要定义自定义的异常时: a) 自定义异常要继承于ApplicationException。 b) 提供自定义的序列化功能。 21. 避免在单个程序集里使用多个Main方法。 22. 只对外公布必要的操作,其他的则为internal。 23. Avoid friend assemblies, as it increases inter-assembly coupling. 24. Avoid code that relies on an assembly running from a particular location. 25. 使应用程序集尽量为最小化代码(EXE客户程序)。使用类库来替换包含的商务逻辑。 26. 避免给枚举变量提供显式的值。 //正确方法 public enum Color { Red,Green,Blue } //避免 public enum Color { Red = 1,Green = 2,Blue = 3 } 27. 避免指定特殊类型的枚举变量。 //避免 public enum Color : long { Red,Green,Blue } 28. 即使if语句只有一句,也要将if语句的内容用大括号扩起来。 29. 避免使用trinary条件操作符。 30. 避免在条件语句调用返回bool值的函数。可以使用局部变量并检查这些局部变量。 bool IsEverythingOK() {…} //避免 if (IsEverythingOK ()) {…} //替换方案 bool ok = IsEverythingOK(); if (ok) {…} 31. 总是使用基于0开始的数组。 32. 在循环总是显式的初始化引用类型的数组。 public class MyClass {} MyClass[] array = new MyClass[100]; for(int index = 0; index < array.Length; index++) { array[index] = new MyClass(); } 33. 不要提供public 和 protected的成员变量,使用属性代替他们。 34. 避免在继承使用new而使用override替换。 35. 在不是sealed的类总是将public 和 protected的方法标记成virtual的。 36. 除非使用interop(COM+ 或其他的dll)代码否则不要使用不安全的代码(unsafe code)。 37. 避免显示的转换,使用as操作符进行兼容类型的转换。 Dog dog = new GermanShepherd(); GermanShepherd shepherd = dog as GermanShepherd; if (shepherd != null ) {…} 38. 当类成员包括委托的时候 a) Copy a delegate to a local variable before publishing to avoid concurrency race condition. b) 在调用委托之前一定要检查它是否为null public class MySource { public event EventHandler MyEvent; public void FireEvent() { EventHandler temp = MyEvent; if(temp != null ) { temp(this,EventArgs.Empty); } } } 39. 不要提供公共的事件成员变量,使用事件访问器替换这些变量。 public class MySource { MyDelegate m_SomeEvent ; public event MyDelegate SomeEvent { add { m_SomeEvent += value; } remove { m_SomeEvent -= value; } } } 40. 使用一个事件帮助类来公布事件的定义。 41. 总是使用接口。 42. 类和接口的方法和属性至少为2:1的比例。 43. 避免一个接口只有一个成员。 44. 尽量使每个接口包含3-5个成员。 45. 接口的成员不应该超过20个。 a) 实际情况可能限制为12个 46. 避免接口成员包含事件。 47. 避免使用抽象方法而使用接口替换。 48. 在类层次显示接口。 49. 推荐使用显式的接口实现。 50. 从不假设一个类型兼容一个接口。Defensively query for that interface. SomeType obj1; IMyInterface obj2; /* 假设已有代码初始化过obj1,接下来 */ obj2 = obj1 as IMyInterface; if (obj2 != null) { obj2.Method1(); } else { //处理错误 } 51. 表现给最终用户的字符串不要使用硬编码而要使用资源文件替换之。 52. 不要硬编码可能更改的基于配置的字符串,比如连接字符串。 53. 当需要构建长的字符串的时候,使用StringBuilder不要使用string 54. 避免在结构里面提供方法。 a) 建议使用参数化构造函数 b) 可以重裁操作符 55. 总是要给静态变量提供静态构造函数。 56. 能使用早期绑定就不要使用后期绑定。 57. 使用应用程序的日志和跟踪。 58. 除非在不完全的switch语句否则不要使用goto语句。 59. 在switch语句总是要有default子句来显示信息(Assert)。 int number = SomeMethod(); switch(number) { case 1: Trace.WriteLine("Case 1:"); break; case 2: Trace.WriteLine("Case 2:"); break; default : Debug.Assert(false); break; } 60. 除非在构造函数调用其他构造函数否则不要使用this指针。 // 正确使用this的例子 public class MyClass { public MyClass(string message ) {} public MyClass() : this("hello") {} } 61. 除非你想重写子类存在名称冲突的成员或者调用基类的构造函数否则不要使用base来访问基类的成员。 // 正确使用base的例子 public class Dog { public Dog(string name) {} virtual public void Bark( int howLong) {} } public class GermanShepherd : Dog { public GermanShe pherd(string name): base (name) {} override public void Bark(int howLong) { base .Bark(howLong); } } 62. 基于模板的时候要实现Dispose()和Finalize()两个方法。 63. 通常情况下避免有从System.Object转换来和由System.Object转换去的代码,而使用强制转换或者as操作符替换。 class SomeClass {} //避免: class MyClass <T> { void SomeMethod(T t) { object temp = t; SomeClass obj = (SomeClass)temp; } } // 正确: class MyClass <T> where T : SomeClass { void SomeMethod(T t) { SomeClass obj = t; } } 64. 在一般情况下不要定影有限制符的接口。接口的限制级别通常可以用强类型来替换之。 public class Customer {…} //避免: public interface IList <T> where T : Customer {…} //正确: public interface ICustomerList : IList <Customer> {…} 65. 不确定在接口内的具体方法的限制条件。 66. 总是选择使用C#内置(一般的generics)的数据结构。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值