一、程序结构javascript
using System; namespace HelloWorldApplication { class HelloWorld { static void Main(string[] args) { /* 个人第一个 C# 程序*/ Console.WriteLine("Hello World"); Console.ReadKey(); } } }
WriteLine 是一个定义在 System 命名空间中的 Console 类的一个方法。该语句会在屏幕上显示消息 "Hello, World!"。java
标识符是用来识别类、变量、函数或任何其它用户定义的项目。在 C# 中,类的命名必须遵循以下基本规则:程序员
值类型直接包含数据。好比 int、char、float,它们分别存储数字、字符、浮点数。c#
下表列出了 C# 2010 中可用的值类型:数组
类型 | 描述 | 范围 | 默认值 |
---|---|---|---|
bool | 布尔值 | True 或 False | False |
byte | 8 位无符号整数 | 0 到 255 | 0 |
char | 16 位 Unicode 字符 | U +0000 到 U +ffff | '\0' |
decimal | 128 位精确的十进制值,28-29 有效位数 | (-7.9 x 1028 到 7.9 x 1028) / 100 到 28 | 0.0M |
double | 64 位双精度浮点型 | (+/-)5.0 x 10-324 到 (+/-)1.7 x 10308 | 0.0D |
float | 32 位单精度浮点型 | -3.4 x 1038 到 + 3.4 x 1038 | 0.0F |
int | 32 位有符号整数类型 | -2,147,483,648 到 2,147,483,647 | 0 |
long | 64 位有符号整数类型 | -923,372,036,854,775,808 到 9,223,372,036,854,775,807 | 0L |
sbyte | 8 位有符号整数类型 | -128 到 127 | 0 |
short | 16 位有符号整数类型 | -32,768 到 32,767 | 0 |
uint | 32 位无符号整数类型 | 0 到 4,294,967,295 | 0 |
ulong | 64 位无符号整数类型 | 0 到 18,446,744,073,709,551,615 | 0 |
ushort | 16 位无符号整数类型 | 0 到 65,535 | 0 |
如需获得一个类型或一个变量在特定平台上的准确尺寸,可使用 sizeof 方法。表达式 sizeof(type) 产生以字节为单位存储对象或类型的存储尺寸。安全
引用类型不包含存储在变量中的实际数据,但它们包含对变量的引用。它们指的是一个内存位置。使用多个变量时,引用类型能够指向一个内存位置。若是内存位置的数据是由一个变量改变的,其余变量会自动反映这种值的变化。内置的 引用类型有:object、dynamic 和 string。数据结构
对象类型:对象(Object)类型能够被分配任何其余类型(值类型、引用类型、预约义类型或用户自定义类型)的值。可是,在分配值以前,须要先进行类型转换。app
当一个值类型转换为对象类型时,则被称为 装箱;另外一方面,当一个对象类型转换为值类型时,则被称为 拆箱。ide
object obj; obj = 100; // 这是装箱
能够存储任何类型的值在动态数据类型变量中。这些变量的类型检查是在运行时发生的。函数
dynamic d = 20;
动态类型与对象类型类似,可是对象类型变量的类型检查是在编译时发生的,而动态类型变量的类型检查是在运行时发生的。
字符串(String)类型 容许您给变量分配任何字符串值。字符串(String)类型是 System.String 类的别名。它是从对象(Object)类型派生的。字符串(String)类型的值能够经过两种形式进行分配:引号和 @引号。
String str = "runoob.com"; 或: @"runoob.com"; C# string 字符串的前面能够加 @(称做"逐字字符串")将转义字符(\)看成普通字符对待,好比: string str = @"C:\Windows"; 等价于: string str = "C:\\Windows"; @ 字符串中能够任意换行,换行符及缩进空格都计算在字符串长度以内。 string str = @"<script type=""text/javascript""> <!-- --> </script>";
type* identifier;
c#中,类型转换(或者叫作类型铸造)有两种形式:
namespace TypeConversionApplication { class ExplicitConversion { static void Main(string[] args) { double d = 5673.74; int i; // 强制转换 double 为 int i = (int)d; Console.WriteLine(i); Console.ReadKey(); } } }
C# 提供了下列内置的类型转换方法:
序号 | 方法 & 描述 |
---|---|
1 | ToBoolean 若是可能的话,把类型转换为布尔型。 |
2 | ToByte 把类型转换为字节类型。 |
3 | ToChar 若是可能的话,把类型转换为单个 Unicode 字符类型。 |
4 | ToDateTime 把类型(整数或字符串类型)转换为 日期-时间 结构。 |
5 | ToDecimal 把浮点型或整数类型转换为十进制类型。 |
6 | ToDouble 把类型转换为双精度浮点型。 |
7 | ToInt16 把类型转换为 16 位整数类型。 |
8 | ToInt32 把类型转换为 32 位整数类型。 |
9 | ToInt64 把类型转换为 64 位整数类型。 |
10 | ToSbyte 把类型转换为有符号字节类型。 |
11 | ToSingle 把类型转换为小浮点数类型。 |
12 | ToString 把类型转换为字符串类型。 |
13 | ToType 把类型转换为指定类型。 |
14 | ToUInt16 把类型转换为 16 位无符号整数类型。 |
15 | ToUInt32 把类型转换为 32 位无符号整数类型。 |
16 | ToUInt64 把类型转换为 64 位无符号整数类型。 |
下面的实例把不一样值的类型转换为字符串类型:
namespace TypeConversionApplication { class StringConversion { static void Main(string[] args) { int i = 75; float f = 53.005f; double d = 2345.7652; bool b = true; Console.WriteLine(i.ToString()); Console.WriteLine(f.ToString()); Console.WriteLine(d.ToString()); Console.WriteLine(b.ToString()); Console.ReadKey(); } } }
C# 中变量定义的语法:
<data_type> <variable_list>;
data_type 必须是一个有效的 C# 数据类型,能够是 char、int、float、double 或其余用户自定义的数据类型。variable_list 能够由一个或多个用逗号分隔的标识符名称组成。
System 命名空间中的 Console 类提供了一个函数 ReadLine(),用于接收来自用户的输入,并把它存储到一个变量中。
int num; num = Convert.ToInt32(Console.ReadLine());
函数 Convert.ToInt32() 把用户输入的数据转换为 int 数据类型,由于 Console.ReadLine() 只接受字符串格式的数据。
常量是使用 const 关键字来定义的 。
public const int c1 = 5;
a、整数常量:
整数常量能够是十进制、八进制或十六进制的常量。前缀指定基数:0x 或 0X 表示十六进制,0 表示八进制,没有前缀则表示十进制。整数常量也能够有后缀,能够是 U 和 L 的组合,其中,U 和 L 分别表示 unsigned 和 long。后缀能够是大写或者小写,多个后缀以任意顺序进行组合。
212 /* 合法 */ 215u /* 合法 */ 0xFeeL /* 合法 */ 078 /* 非法:8 不是一个八进制数字 */ 032UU /* 非法:不能重复后缀 */
如下是各类类型的整数常量的实例:
85 /* 十进制 */ 0213 /* 八进制 */ 0x4b /* 十六进制 */ 30 /* int */ 30u /* 无符号 int */ 30l /* long */ 30ul /* 无符号 long */
b、浮点常量:
个浮点常量是由整数部分、小数点、小数部分和指数部分组成。您可使用小数形式或者指数形式来表示浮点常量。使用小数形式表示时,必须包含小数点、指数或同时包含二者。使用指数形式表示时,必须包含整数部分、小数部分或同时包含二者。有符号的指数是用 e 或 E 表示的。
3.14159 /* 合法 */ 314159E-5L /* 合法 */ 510E /* 非法:不彻底指数 */ 210f /* 非法:没有小数或指数 */ .e55 /* 非法:缺乏整数或小数 */
c、字符常量
字符常量是括在单引号里,例如,'x',且可存储在一个简单的字符类型变量中。一个字符常量能够是一个普通字符(例如 'x')、一个转义序列(例如 '\t')或者一个通用字符(例如 '\u02C0')。
在 C# 中有一些特定的字符,当它们的前面带有反斜杠时有特殊的意义,可用于表示换行符(\n)或制表符 tab(\t)。
转义序列 | 含义 |
---|---|
\\ | \ 字符 |
\' | ' 字符 |
\" | " 字符 |
\? | ? 字符 |
\a | Alert 或 bell |
\b | 退格键(Backspace) |
\f | 换页符(Form feed) |
\n | 换行符(Newline) |
\r | 回车 |
\t | 水平制表符 tab |
\v | 垂直制表符 tab |
\ooo | 一到三位的八进制数 |
\xhh . . . | 一个或多个数字的十六进制数 |
d、字符串常量
string c = "hello \t world"; // hello world string d = @"hello \t world"; // hello \t world string e = "Joe said \"Hello\" to me"; // Joe said "Hello" to me string f = @"Joe said ""Hello"" to me"; // Joe said "Hello" to me string g = "\\\\server\\share\\file.txt"; // \\server\share\file.txt string h = @"\\server\share\file.txt"; // \\server\share\file.txt
封装 被定义为"把一个或多个项目封闭在一个物理的或者逻辑的包中"。在面向对象程序设计方法论中,封装是为了防止对实现细节的访问。
C# 封装根据具体的须要,设置使用者的访问权限,并经过 访问修饰符 来实现。一个 访问修饰符 定义了一个类成员的范围和可见性。C# 支持的访问修饰符以下所示:
若是没有指定访问修饰符,则使用类成员的默认访问修饰符,即为 private。
<Access Specifier> <Return Type> <Method Name>(Parameter List) { Method Body }
方法调用的时候有三种传递参数的方法:值参数、引用参数、输出参数;
a、值参数
普通的方法调用便是用的这种参数,实际参数的值会复制给形参,实参和形参使用的是两个不一样内存中的值。因此,当形参的值发生改变时,不会影响实参的值,从而保证了实参数据的安全。
b、引用参数
引用参数表示与提供给方法的实际参数具备相同的内存位置。因此当方法内的形参发生改变时,调用方法时传递的实参也会发生变化;
...... public void swap(ref int x, ref int y) ...... /* 调用函数来交换值 */ n.swap(ref a, ref b); ......
在c#中,这种参数使用的时候在形参和实参前加上ref关键字
c、按输出传递参数
输出参数会把方法输出的数据赋给本身,其余方面与引用参数类似。
namespace CalculatorApplication { class NumberManipulator { public void getValues(out int x, out int y ) { Console.WriteLine("请输入第一个值: "); x = Convert.ToInt32(Console.ReadLine()); Console.WriteLine("请输入第二个值: "); y = Convert.ToInt32(Console.ReadLine()); } static void Main(string[] args) { NumberManipulator n = new NumberManipulator(); /* 局部变量定义 */ int a , b; /* 调用函数来获取值 */ n.getValues(out a, out b); Console.WriteLine("在方法调用以后,a 的值: {0}", a); Console.WriteLine("在方法调用以后,b 的值: {0}", b); Console.ReadLine(); } } }
当须要从一个参数没有指定初始值的方法中返回值时,输出参数特别有用。上例中若是改成引用参数因为没有给参数制定初始值,会出现报错。
C# 提供了一个特殊的数据类型,nullable 类型(可空类型),用于对 int,double,bool 等没法直接赋值为 null 的数据类型进行 null 的赋值,可空类型能够表示其基础值类型正常范围内的值,再加上一个 null 值。
例如,Nullable< Int32 >,读做"可空的 Int32",能够被赋值为 -2,147,483,648 到 2,147,483,647 之间的任意值,也能够被赋值为 null 值。相似的,Nullable< bool > 变量能够被赋值为 true 或 false 或 null。
int? num1 = null; int? num2 = 45; double? num3 = new double?(); double? num4 = 3.14157; bool? boolval = new bool?();
Null 合并运算符
Null 合并运算符把操做数类型隐式转换为另外一个可空(或不可空)的值类型的操做数的类型。若是第一个操做数的值为 null,则运算符返回第二个操做数的值,不然返回第一个操做数的值。
double? num1 = null; double? num2 = 3.14157; double num3; num3 = num1 ?? 5.34; // num1 若是为空值则返回 5.34 Console.WriteLine("num3 的值: {0}", num3); num3 = num2 ?? 5.34; Console.WriteLine("num3 的值: {0}", num3);
double[] balance = new double[10];
赋值:能够经过使用索引号赋值给一个单独的数组元素:
double[] balance = new double[10]; balance[0] = 4500.0;
能够在声明数组的同时给数组赋值:
double[] balance = { 2340.0, 4523.69, 3421.0};
也能够建立并初始化一个数组:
int [] marks = new int[5] { 99, 98, 92, 97, 95};
能够省略数组的大小:
int [] marks = new int[] { 99, 98, 92, 97, 95};
建立一个数组时,C# 编译器会根据数组类型隐式初始化每一个数组元素为一个默认值。例如,int 数组的全部元素都会被初始化为 0。
建立一个二维数组:
int [,] a = new int [3,4] { {0, 1, 2, 3} , /* 初始化索引号为 0 的行 */ {4, 5, 6, 7} , /* 初始化索引号为 1 的行 */ {8, 9, 10, 11} /* 初始化索引号为 2 的行 */ };
建立的时候用逗号隔开,同理能够建立多维数组。
交错数组
交错数组是数组的数组。
/* 一个由 5 个整型数组组成的交错数组 */ int[][] a = new int[][]{new int[]{0,0},new int[]{1,2}, new int[]{2,4},new int[]{ 3, 6 }, new int[]{ 4, 8 } };
参数数组
有时,当声明一个方法时,您不能肯定要传递给函数做为参数的参数数目。C# 参数数组解决了这个问题,参数数组一般用于传递未知数量的参数给函数(相似于js中的argument)。
...... public int AddElements(params int[] arr) { int sum = 0; foreach (int i in arr) { sum += i; } return sum; } ...... int sum = app.AddElements(512, 720, 250, 567, 889); ......
Array 类
Array 类是 C# 中全部数组的基类,它是在 System 命名空间中定义。Array 类提供了各类用于数组的属性和方法。
序号 | 属性 & 描述 |
---|---|
1 | IsFixedSize 获取一个值,该值指示数组是否带有固定大小。 |
2 | IsReadOnly 获取一个值,该值指示数组是否只读。 |
3 | Length 获取一个 32 位整数,该值表示全部维度的数组中的元素总数。 |
4 | LongLength 获取一个 64 位整数,该值表示全部维度的数组中的元素总数。 |
5 | Rank 获取数组的秩(维度)。 |
Array的一些经常使用方法:
序号 | 方法 & 描述 |
---|---|
1 | Clear 根据元素的类型,设置数组中某个范围的元素为零、为 false 或者为 null。 |
2 | Copy(Array, Array, Int32) 从数组的第一个元素开始复制某个范围的元素到另外一个数组的第一个元素位置。长度由一个 32 位整数指定。 |
3 | CopyTo(Array, Int32) 从当前的一维数组中复制全部的元素到一个指定的一维数组的指定索引位置。索引由一个 32 位整数指定。 |
4 | GetLength 获取一个 32 位整数,该值表示指定维度的数组中的元素总数。 |
5 | GetLongLength 获取一个 64 位整数,该值表示指定维度的数组中的元素总数。 |
6 | GetLowerBound 获取数组中指定维度的下界。 |
7 | GetType 获取当前实例的类型。从对象(Object)继承。 |
8 | GetUpperBound 获取数组中指定维度的上界。 |
9 | GetValue(Int32) 获取一维数组中指定位置的值。索引由一个 32 位整数指定。 |
10 | IndexOf(Array, Object) 搜索指定的对象,返回整个一维数组中第一次出现的索引。 |
11 | Reverse(Array) 逆转整个一维数组中元素的顺序。 |
12 | SetValue(Object, Int32) 给一维数组中指定位置的元素设置值。索引由一个 32 位整数指定。 |
13 | Sort(Array) 使用数组的每一个元素的 IComparable 实现来排序整个一维数组中的元素。 |
14 | ToString 返回一个表示当前对象的字符串。从对象(Object)继承。 |
如需了解 Array 类的完整的方法列表,请参阅微软的 C# 文档。
int[] list = { 34, 72, 13, 44, 25, 30, 10 }; Console.Write("原始数组: "); foreach (int i in list) { Console.Write(i + " "); } Console.WriteLine(); // 逆转数组 Array.Reverse(list); Console.Write("逆转数组: "); foreach (int i in list) { Console.Write(i + " "); } Console.WriteLine(); // 排序数组 Array.Sort(list); Console.Write("排序数组: "); foreach (int i in list) { Console.Write(i + " "); } Console.WriteLine();
//字符串,字符串链接 string fname, lname; fname = "Rowan"; lname = "Atkinson"; string fullname = fname + lname; Console.WriteLine("Full Name: {0}", fullname); //经过使用 string 构造函数 char[] letters = { 'H', 'e', 'l', 'l','o' }; string greetings = new string(letters); Console.WriteLine("Greetings: {0}", greetings); //方法返回字符串 string[] sarray = { "Hello", "From", "Tutorials", "Point" }; string message = String.Join(" ", sarray); Console.WriteLine("Message: {0}", message); //用于转化值的格式化方法 DateTime waiting = new DateTime(2012, 10, 10, 17, 58, 1); string chat = String.Format("Message sent at {0:t} on {0:D}", waiting); Console.WriteLine("Message: {0}", chat); Console.ReadKey() ;
String 类有许多方法用于 string 对象的操做。下面的表格提供了一些最经常使用的方法:
序号 | 方法名称 & 描述 |
---|---|
1 | public static int Compare( string strA, string strB ) 比较两个指定的 string 对象,并返回一个表示它们在排列顺序中相对位置的整数。该方法区分大小写。 |
2 | public static int Compare( string strA, string strB, bool ignoreCase ) 比较两个指定的 string 对象,并返回一个表示它们在排列顺序中相对位置的整数。可是,若是布尔参数为真时,该方法不区分大小写。 |
3 | public static string Concat( string str0, string str1 ) 链接两个 string 对象。 |
4 | public static string Concat( string str0, string str1, string str2 ) 链接三个 string 对象。 |
5 | public static string Concat( string str0, string str1, string str2, string str3 ) 链接四个 string 对象。 |
6 | public bool Contains( string value ) 返回一个表示指定 string 对象是否出如今字符串中的值。 |
7 | public static string Copy( string str ) 建立一个与指定字符串具备相同值的新的 String 对象。 |
8 | public void CopyTo( int sourceIndex, char[] destination, int destinationIndex, int count ) 从 string 对象的指定位置开始复制指定数量的字符到 Unicode 字符数组中的指定位置。 |
9 | public bool EndsWith( string value ) 判断 string 对象的结尾是否匹配指定的字符串。 |
10 | public bool Equals( string value ) 判断当前的 string 对象是否与指定的 string 对象具备相同的值。 |
11 | public static bool Equals( string a, string b ) 判断两个指定的 string 对象是否具备相同的值。 |
12 | public static string Format( string format, Object arg0 ) 把指定字符串中一个或多个格式项替换为指定对象的字符串表示形式。 |
13 | public int IndexOf( char value ) 返回指定 Unicode 字符在当前字符串中第一次出现的索引,索引从 0 开始。 |
14 | public int IndexOf( string value ) 返回指定字符串在该实例中第一次出现的索引,索引从 0 开始。 |
15 | public int IndexOf( char value, int startIndex ) 返回指定 Unicode 字符从该字符串中指定字符位置开始搜索第一次出现的索引,索引从 0 开始。 |
16 | public int IndexOf( string value, int startIndex ) 返回指定字符串从该实例中指定字符位置开始搜索第一次出现的索引,索引从 0 开始。 |
17 | public int IndexOfAny( char[] anyOf ) 返回某一个指定的 Unicode 字符数组中任意字符在该实例中第一次出现的索引,索引从 0 开始。 |
18 | public int IndexOfAny( char[] anyOf, int startIndex ) 返回某一个指定的 Unicode 字符数组中任意字符从该实例中指定字符位置开始搜索第一次出现的索引,索引从 0 开始。 |
19 | public string Insert( int startIndex, string value ) 返回一个新的字符串,其中,指定的字符串被插入在当前 string 对象的指定索引位置。 |
20 | public static bool IsNullOrEmpty( string value ) 指示指定的字符串是否为 null 或者是否为一个空的字符串。 |
21 | public static string Join( string separator, string[] value ) 链接一个字符串数组中的全部元素,使用指定的分隔符分隔每一个元素。 |
22 | public static string Join( string separator, string[] value, int startIndex, int count ) 链接接一个字符串数组中的指定位置开始的指定元素,使用指定的分隔符分隔每一个元素。 |
23 | public int LastIndexOf( char value ) 返回指定 Unicode 字符在当前 string 对象中最后一次出现的索引位置,索引从 0 开始。 |
24 | public int LastIndexOf( string value ) 返回指定字符串在当前 string 对象中最后一次出现的索引位置,索引从 0 开始。 |
25 | public string Remove( int startIndex ) 移除当前实例中的全部字符,从指定位置开始,一直到最后一个位置为止,并返回字符串。 |
26 | public string Remove( int startIndex, int count ) 从当前字符串的指定位置开始移除指定数量的字符,并返回字符串。 |
27 | public string Replace( char oldChar, char newChar ) 把当前 string 对象中,全部指定的 Unicode 字符替换为另外一个指定的 Unicode 字符,并返回新的字符串。 |
28 | public string Replace( string oldValue, string newValue ) 把当前 string 对象中,全部指定的字符串替换为另外一个指定的字符串,并返回新的字符串。 |
29 | public string[] Split( params char[] separator ) 返回一个字符串数组,包含当前的 string 对象中的子字符串,子字符串是使用指定的 Unicode 字符数组中的元素进行分隔的。 |
30 | public string[] Split( char[] separator, int count ) 返回一个字符串数组,包含当前的 string 对象中的子字符串,子字符串是使用指定的 Unicode 字符数组中的元素进行分隔的。int 参数指定要返回的子字符串的最大数目。 |
31 | public bool StartsWith( string value ) 判断字符串实例的开头是否匹配指定的字符串。 |
32 | public char[] ToCharArray() 返回一个带有当前 string 对象中全部字符的 Unicode 字符数组。 |
33 | public char[] ToCharArray( int startIndex, int length ) 返回一个带有当前 string 对象中全部字符的 Unicode 字符数组,从指定的索引开始,直到指定的长度为止。 |
34 | public string ToLower() 把字符串转换为小写并返回。 |
35 | public string ToUpper() 把字符串转换为大写并返回。 |
36 | public string Trim() 移除当前 String 对象中的全部前导空白字符和后置空白字符。 |
...... if (String.Compare(str1, str2) == 0) ......
结构体是值类型数据结构。它使得一个单一变量能够存储各类数据类型的相关数据。struct 关键字用于建立结构体。结构体是用来表明一个记录。
using System; using System.Text; struct Books { private string title; private string author; private string subject; private int book_id; public void getValues(string t, string a, string s, int id) { title = t; author = a; subject = s; book_id =id; } public void display() { Console.WriteLine("Title : {0}", title); Console.WriteLine("Author : {0}", author); Console.WriteLine("Subject : {0}", subject); Console.WriteLine("Book_id :{0}", book_id); } }; public class testStructure { public static void Main(string[] args) { Books Book1 = new Books(); /* 声明 Book1,类型为 Book */ Books Book2 = new Books(); /* 声明 Book2,类型为 Book */ /* book 1 详述 */ Book1.getValues("C Programming", "Nuha Ali", "C Programming Tutorial",6495407); /* book 2 详述 */ Book2.getValues("Telecom Billing", "Zara Ali", "Telecom Billing Tutorial", 6495700); /* 打印 Book1 信息 */ Book1.display(); /* 打印 Book2 信息 */ Book2.display(); Console.ReadKey(); } }
结构体和类的不一样:
构造函数
类的 构造函数 是类的一个特殊的成员函数,当建立类的新对象时执行。构造函数的名称与类的名称彻底相同,它没有任何返回类型。
默认的构造函数没有任何参数。可是若是你须要一个带有参数的构造函数能够有参数,这种构造函数叫作参数化构造函数。
class Line { private double length; // 线条的长度 public Line(double len) // 参数化构造函数 { Console.WriteLine("对象已建立,length = {0}", len); length = len; } public void setLength( double len ) { length = len; } public double getLength() { return length; } static void Main(string[] args) { Line line = new Line(10.0); Console.WriteLine("线条的长度: {0}", line.getLength()); // 设置线条长度 line.setLength(6.0); Console.WriteLine("线条的长度: {0}", line.getLength()); Console.ReadKey(); } }
折构函数
类的 析构函数 是类的一个特殊的成员函数,当类的对象超出范围时执行。
析构函数的名称是在类的名称前加上一个波浪形(~)做为前缀,它不返回值,也不带任何参数。
析构函数用于在结束程序(好比关闭文件、释放内存等)以前释放资源。析构函数不能继承或重载。
class Line { private double length; // 线条的长度 public Line() // 构造函数 { Console.WriteLine("对象已建立"); } ~Line() //析构函数 { Console.WriteLine("对象已删除"); } public void setLength( double len ) { length = len; } public double getLength() { return length; } static void Main(string[] args) { Line line = new Line(); // 设置线条长度 line.setLength(6.0); Console.WriteLine("线条的长度: {0}", line.getLength()); } }
静态成员
咱们可使用 static 关键字把类成员定义为静态的。当咱们声明一个类成员为静态时,意味着不管有多少个类的对象被建立,只会有一个该静态成员的副本。
关键字 static 意味着类中只有一个该成员的实例。静态变量用于定义常量,由于它们的值能够经过直接调用类而不须要建立类的实例来获取。静态变量可在成员函数或类的定义外部进行初始化。你也能够在类的定义内部初始化静态变量。
class StaticVar { public static int num; public void count() { num++; } public int getNum() { return num; } } class StaticTester { static void Main(string[] args) { StaticVar s1 = new StaticVar(); StaticVar s2 = new StaticVar(); s1.count(); s1.count(); s1.count(); s2.count(); s2.count(); s2.count(); Console.WriteLine("s1 的变量 num: {0}", s1.getNum()); Console.WriteLine("s2 的变量 num: {0}", s2.getNum()); Console.ReadKey(); } }
在上面这个例子中,num被定义成一个静态成员,因此无论后续该类被调用几回,该成员只使用这一个副本。num初始值为0,在Main中被s1和s2一共累加6次,因此最后结果s1和s2的输出都是6。
当建立一个类时,不须要彻底从新编写新的数据成员和成员函数,只须要设计一个新的类,继承了已有的类的成员便可。这个已有的类被称为的基类,这个新的类被称为派生类。
using System; namespace RectangleApplication { class Rectangle { // 成员变量 protected double length; protected double width; public Rectangle(double l, double w) { length = l; width = w; } public double GetArea() { return length * width; } public void Display() { Console.WriteLine("长度: {0}", length); Console.WriteLine("宽度: {0}", width); Console.WriteLine("面积: {0}", GetArea()); } }//end class Rectangle class Tabletop : Rectangle { private double cost; public Tabletop(double l, double w) : base(l, w) { } public double GetCost() { double cost; cost = GetArea() * 70; return cost; } public void Display() { base.Display(); Console.WriteLine("成本: {0}", GetCost()); } } class ExecuteRectangle { static void Main(string[] args) { Tabletop t = new Tabletop(4.5, 7.5); t.Display(); Console.ReadLine(); } } }
若是派生类和基类中存在相同命名的成员,那么在派生类中要经过base来调用基类中的成员
C# 不支持多重继承。可是,可使用接口来实现多重继承。
重载是能够在同一个范围内对相同的函数名有多个定义。函数的定义必须彼此不一样,能够是参数列表中的参数类型不一样,也能够是参数个数不一样。不能重载只有返回类型不一样的函数声明。
void print(int i) { Console.WriteLine("Printing int: {0}", i ); } void print(double f) { Console.WriteLine("Printing float: {0}" , f); } void print(string s) { Console.WriteLine("Printing string: {0}", s); } static void Main(string[] args) { Printdata p = new Printdata(); // 调用 print 来打印整数 p.print(5); // 调用 print 来打印浮点数 p.print(500.263); // 调用 print 来打印字符串 p.print("Hello C++"); Console.ReadKey(); }
命名空间的设计目的是提供一种让一组名称与其余名称分隔开的方式。在一个命名空间中声明的类的名称与另外一个命名空间中声明的相同的类的名称不冲突。
namespace_name.item_name;
前面的是名空间的名称, 点后面的是支持命名空间版本的函数或变量(类名)。
using 关键字
using 关键字代表程序使用的是给定命名空间中的名称。也可使用 using 命名空间指令,这样在使用的时候就不用在前面加上命名空间名称。该指令告诉编译器随后的代码使用了指定命名空间中的名称。
using System; using first_space; using second_space; namespace first_space { class abc { public void func() { Console.WriteLine("Inside first_space"); } } } namespace second_space { class efg { public void func() { Console.WriteLine("Inside second_space"); } } } class TestClass { static void Main(string[] args) { abc fc = new abc(); efg sc = new efg(); fc.func(); sc.func(); Console.ReadKey(); } }
可使用点(.)运算符访问嵌套的命名空间的成员
using SomeNameSpace.Nested;
预处理器指令指导编译器在实际编译开始以前对信息进行预处理。
预处理器指令 | 描述 |
---|---|
#define | 它用于定义一系列成为符号的字符。 |
#undef | 它用于取消定义符号。 |
#if | 它用于测试符号是否为真。 |
#else | 它用于建立复合条件指令,与 #if 一块儿使用。 |
#elif | 它用于建立复合条件指令。 |
#endif | 指定一个条件指令的结束。 |
#line | 它可让您修改编译器的行数以及(可选地)输出错误和警告的文件名。 |
#error | 它容许从代码的指定位置生成一个错误。 |
#warning | 它容许从代码的指定位置生成一级警告。 |
#region | 它可让您在使用 Visual Studio Code Editor 的大纲特性时,指定一个可展开或折叠的代码块。 |
#endregion | 它标识着 #region 块的结束。 |
#define 容许您定义一个符号,这样,经过使用符号做为传递给 #if 指令的表达式,表达式将返回 true。
#define PI using System; namespace PreprocessorDAppl { class Program { static void Main(string[] args) { #if (PI) Console.WriteLine("PI is defined"); #else Console.WriteLine("PI is not defined"); #endif Console.ReadKey(); } } }
一个以 #if 指令开始的条件指令,必须显示地以一个 #endif 指令终止。
预处理器指令的用途理解:
在程序调试和运行上有重要的做用。好比预处理器指令能够禁止编译器编译代码的某一部分,若是计划发布两个版本的代码,即基本版本和有更多功能的企业版本,就可使用这些预处理器指令来控制。在编译软件的基本版本时,使用预处理器指令还能够禁止编译器编译于额外功能相关的代码。另外,在编写提供调试信息的代码时,也可使用预处理器指令进行控制。总的来讲和普通的控制语句(if等)功能相似,方便在于预处理器指令包含的未执行部分是不须要编译的。
异常提供了一种把程序控制权从某个部分转移到另外一个部分的方式。
异常类
C# 异常是使用类来表示的。C# 中的异常类主要是直接或间接地派生于 System.Exception 类。System.ApplicationException 和 System.SystemException 类是派生于 System.Exception 类的异常类。
System.ApplicationException 类支持由应用程序生成的异常。因此程序员定义的异常都应派生自该类。
System.SystemException 类是全部预约义的系统异常的基类。
异常类 | 描述 |
---|---|
System.IO.IOException | 处理 I/O 错误。 |
System.IndexOutOfRangeException | 处理当方法指向超出范围的数组索引时生成的错误。 |
System.ArrayTypeMismatchException | 处理当数组类型不匹配时生成的错误。 |
System.NullReferenceException | 处理当依从一个空对象时生成的错误。 |
System.DivideByZeroException | 处理当除以零时生成的错误。 |
System.InvalidCastException | 处理在类型转换期间生成的错误。 |
System.OutOfMemoryException | 处理空闲内存不足生成的错误。 |
System.StackOverflowException | 处理栈溢出生成的错误。 |
异常处理
C# 以 try 和 catch 块的形式提供了一种结构化的异常处理方案。使用这些块,把核心程序语句与错误处理语句分离开。
这些错误处理块是使用 try、catch 和 finally 关键字实现的。
一个 文件 是一个存储在磁盘中带有指定名称和目录路径的数据集合。当打开文件进行读写时,它变成一个 流。
从根本上说,流是经过通讯路径传递的字节序列。有两个主要的流:输入流 和 输出流。输入流用于从文件读取数据(读操做),输出流用于向文件写入数据(写操做)。
System.IO类
System.IO 命名空间有各类不一样的类,用于执行各类文件操做,如建立和删除文件、读取或写入文件,关闭文件等。
I/O 类 | 描述 |
---|---|
BinaryReader | 从二进制流读取原始数据。 |
BinaryWriter | 以二进制格式写入原始数据。 |
BufferedStream | 字节流的临时存储。 |
Directory | 有助于操做目录结构。 |
DirectoryInfo | 用于对目录执行操做。 |
DriveInfo | 提供驱动器的信息。 |
File | 有助于处理文件。 |
FileInfo | 用于对文件执行操做。 |
FileStream | 用于文件中任何位置的读写。 |
MemoryStream | 用于随机访问存储在内存中的数据流。 |
Path | 对路径信息执行操做。 |
StreamReader | 用于从字节流中读取字符。 |
StreamWriter | 用于向一个流中写入字符。 |
StringReader | 用于读取字符串缓冲区。 |
StringWriter | 用于写入字符串缓冲区。 |
FileStream 类
System.IO 命名空间中的 FileStream 类有助于文件的读写与关闭。该类派生自抽象类 Stream。
您须要建立一个 FileStream 对象来建立一个新的文件,或打开一个已有的文件。例如,建立一个 FileStream 对象 F 来读取名为 sample.txt 的文件:
FileStream F = new FileStream("sample.txt", FileMode.Open, FileAccess.Read, FileShare.Read);
参数 | 描述 |
---|---|
FileMode | FileMode 枚举定义了各类打开文件的方法。FileMode 枚举的成员有:
|
FileAccess | FileAccess 枚举的成员有:Read、ReadWrite 和 Write。 |
FileShare | FileShare 枚举的成员有:
|
class Program { static void Main(string[] args) { FileStream F = new FileStream("test.dat", FileMode.OpenOrCreate, FileAccess.ReadWrite); for (int i = 1; i <= 20; i++) { F.WriteByte((byte)i); } F.Position = 0; for (int i = 0; i <= 20; i++) { Console.Write(F.ReadByte() + " "); } F.Close(); Console.ReadKey(); } }
StreamReader 类(表示阅读器读取一系列字符)
序号 | 方法 & 描述 |
---|---|
1 | public override void Close() 关闭 StreamReader 对象和基础流,并释听任何与读者相关的系统资源。 |
2 | public override int Peek() 返回下一个可用的字符,但不使用它。 |
3 | public override int Read() 从输入流中读取下一个字符,并把字符位置往前移一个字符。 |
下面的实例演示了读取名为 Jamaica.txt 的文件。文件以下:
Down the way where the nights are gay And the sun shines daily on the mountain top I took a trip on a sailing ship And when I reached Jamaica I made a stop
编译和执行上面的程序时,它会显示文件的内容。
static void Main(string[] args) { try { // 建立一个 StreamReader 的实例来读取文件 // using 语句也能关闭 StreamReader using (StreamReader sr = new StreamReader("c:/jamaica.txt")) { string line; // 从文件读取并显示行,直到文件的末尾 while ((line = sr.ReadLine()) != null) { Console.WriteLine(line); } } } catch (Exception e) { // 向用户显示出错消息 Console.WriteLine("The file could not be read:"); Console.WriteLine(e.Message); } Console.ReadKey(); }
StreamWriter 类(表示编写器写入一系列字符)
序号 | 方法 & 描述 |
---|---|
1 | public override void Close() 关闭当前的 StreamWriter 对象和基础流。 |
2 | public override void Flush() 清理当前编写器的全部缓冲区,使得全部缓冲数据写入基础流。 |
3 | public virtual void Write(bool value) 把一个布尔值的文本表示形式写入到文本字符串或流。(继承自 TextWriter。) |
4 | public override void Write( char value ) 把一个字符写入到流。 |
5 | public virtual void Write( decimal value ) 把一个十进制值的文本表示形式写入到文本字符串或流。 |
6 | public virtual void Write( double value ) 把一个 8 字节浮点值的文本表示形式写入到文本字符串或流。 |
7 | public virtual void Write( int value ) 把一个 4 字节有符号整数的文本表示形式写入到文本字符串或流。 |
8 | public override void Write( string value ) 把一个字符串写入到流。 |
9 | public virtual void WriteLine() 把行结束符写入到文本字符串或流。 |
使用 StreamWriter 类向文件写入文本数据:
string[] names = new string[] {"Zara Ali", "Nuha Ali"}; using (StreamWriter sw = new StreamWriter("names.txt")) { foreach (string s in names) { sw.WriteLine(s); } } // 从文件中读取并显示每行 string line = ""; using (StreamReader sr = new StreamReader("names.txt")) { while ((line = sr.ReadLine()) != null) { Console.WriteLine(line); } } Console.ReadKey();
---恢复内容结束---