上期回顾 - https://www.cnblogs.com/liu-jinxin/p/10824638.html
一、方法
一个方法是把一些相关的语句组织在一起,用来执行一个任务的语句块。每一个 C# 程序至少有一个带有 Main 方法的类。
要使用一个方法,您需要:定义方法;调用方法。
(一)、简介
语法:
<Access Specifier> <Return Type> <Method Name>(Parameter List)
{
Method Body
}
含义:
-
-
- Access Specifier:访问修饰符,这个决定了变量或方法对于另一个类的可见性。
- Return type:返回类型,一个方法可以返回一个值。返回类型是方法返回的值的数据类型。如果方法不返回任何值,则返回类型为 void。
- Method name:方法名称,是一个唯一的标识符,且是大小写敏感的。它不能与类中声明的其他标识符相同。
- Parameter list:参数列表,使用圆括号括起来,该参数是用来传递和接收方法的数据。参数列表是指方法的参数类型、顺序和数量。参数是可选的,也就是说,一个方法可能不包含参数。
- Method body:方法主体,包含了完成任务所需的指令集。
-
示例代码:
1 class NumberManipulator 2 { 3 public int FindMax(int num1, int num2) 4 { 5 /* 局部变量声明 */ 6 int result; 7 8 if (num1 > num2) 9 result = num1; 10 else 11 result = num2; 12 13 return result; 14 } 15 //可填写其他方法 16 }
调用方法示例代码:
1 using System; 2 3 namespace CalculatorApplication 4 { 5 class NumberManipulator 6 { 7 public int FindMax(int num1, int num2) 8 { 9 /* 局部变量声明 */ 10 int result; 11 12 if (num1 > num2) 13 result = num1; 14 else 15 result = num2; 16 17 return result; 18 } 19 static void Main(string[] args) 20 { 21 /* 局部变量定义 */ 22 int a = 100; 23 int b = 200; 24 int ret; 25 NumberManipulator n = new NumberManipulator(); 26 27 //调用 FindMax 方法 28 ret = n.FindMax(a, b); 29 Console.WriteLine("最大值是: {0}", ret ); 30 Console.ReadLine(); 31 } 32 } 33 } 34 //此示例是在同一个类内调用,也可在不同类,不同命名空间中调用。
(二)、参数传递
当调用带有参数的方法时,您需要向方法传递参数。在 C# 中,有三种向方法传递参数的方式:
方式 | 描述 |
---|---|
值参数 | 这种方式复制参数的实际值给函数的形式参数,实参和形参使用的是两个不同内存中的值。在这种情况下,当形参的值发生改变时,不会影响实参的值,从而保证了实参数据的安全。 |
引用参数 | 这种方式复制参数的内存位置的引用给形式参数。这意味着,当形参的值发生改变时,同时也改变实参的值。 |
输出参数 | 这种方式可以返回多个值。 |
1、按值传递参数
这是参数传递的默认方式。在这种方式下,当调用一个方法时,会为每个值参数创建一个新的存储位置。
实际参数的值会复制给形参,实参和形参使用的是两个不同内存中的值。所以,当形参的值发生改变时,不会影响实参的值,从而保证了实参数据的安全。
实例代码:
using System; namespace CalculatorApplication { class NumberManipulator { public void swap(int a) { a=2; } static void Main(string[] args) { NumberManipulator n = new NumberManipulator(); /* 局部变量定义 */ int a = 1; Console.WriteLine("在交换之前,a 的值: {0}", a); /* 调用函数来交换值 */ n.swap(a); Console.WriteLine("在交换之后,a 的值: {0}", a); Console.ReadLine(); } } } //执行结果: //在交换之前,a 的值:1 //在交换之前,a 的值:1
2、按引用传递参数
引用参数是一个对变量的内存位置的引用。当按引用传递参数时,与值参数不同的是,它不会为这些参数创建一个新的存储位置。引用参数表示与提供给方法的实际参数具有相同的内存位置。
实例代码:
using System; namespace CalculatorApplication { class NumberManipulator { public void swap(ref int a) { a=2; } static void Main(string[] args) { NumberManipulator n = new NumberManipulator(); /* 局部变量定义 */ int a = 1; Console.WriteLine("在交换之前,a 的值: {0}", a); /* 调用函数来交换值 */ n.swap(ref a); Console.WriteLine("在交换之后,a 的值: {0}", a); Console.ReadLine(); } } } //执行结果: //在交换之前,a 的值:1 //在交换之前,a 的值:2
3、按输出传递参数
return 语句可用于只从函数中返回一个值。但是,可以使用 输出参数 来从函数中返回两个值。输出参数会把方法输出的数据赋给自己,其他方面与引用参数相似。
实例代码:
1 using System; 2 namespace CalculatorApplication 3 { 4 class NumberManipulator 5 { 6 public void getValue(out int a ) 7 { 8 a = 2; 9 } 10 11 static void Main(string[] args) 12 { 13 NumberManipulator n = new NumberManipulator(); 14 /* 局部变量定义 */ 15 int a = 1; 16 17 Console.WriteLine("在方法调用之前,a 的值: {0}", a); 18 19 /* 调用函数来获取值 */ 20 n.getValue(out a); 21 22 Console.WriteLine("在方法调用之后,a 的值: {0}", a); 23 Console.ReadLine(); 24 25 } 26 } 27 } 28 //执行结果: 29 //在方法调用之前,a 的值: 1 30 //在方法调用之后,a 的值: 2
我们发现,ref和out似乎可以实现相同的功能,因为都可以改变传递到方法中的变量的值,但是二者本质的区别就是,ref是传入值,out是传出值,在含有out关键之的方法中,变量 必须有方法参数中不含out(可以是ref)的变量赋值或者由全局(即方法可以使用的该方法外部变量)变量赋值,out的宗旨是保证每一个传出变量都必须被赋值。在传入变量的时候,out关键字的变量可以不被初始化,但是没有out 关键字的值要被赋值。而ref参数在传递给方法是,就已经被赋值了,所以ref侧重修改,out侧重输出。
二、可空类型
(一)、单问号 ? 与 双问号 ??
单问号用于对 int,double,bool 等无法直接赋值为 null 的数据类型进行 null 的赋值,意思是这个数据类型是 NullAble 类型的。
int? i = 3 等同于 Nullable<int> i = new Nullable<int>(3);
int i; //默认值0
int? ii; //默认值null
双问号 可用于判断一个变量在为 null 时返回一个指定的值。
(二)、Nullable
C# 提供了一个特殊的数据类型,nullable 类型(可空类型),可空类型可以表示其基础值类型正常范围内的值,再加上一个 null 值。
例如 : Nullable< Int32 >,读作"可空的 Int32",可以被赋值为 -2,147,483,648 到 2,147,483,647 之间的任意值,也可以被赋值为 null 值。
Nullable< bool > 变量可以被赋值为 true 或 false 或 null。
在处理数据库和其他包含可能未赋值的元素的数据类型时,将 null 赋值给数值类型或布尔型的功能特别有用。例如,数据库中的布尔型字段可以存储值 true 或 false,或者,该字段也可以未定义。
语法:< data_type> ? <variable_name> = null;
示例代码:
1 using System; 2 namespace CalculatorApplication 3 { 4 class NullablesAtShow 5 { 6 static void Main(string[] args) 7 { 8 int? num1 = null; 9 int? num2 = 45; 10 double? num3 = new double?(); 11 double? num4 = 3.14157; 12 13 bool? boolval = new bool?(); 14 15 // 显示值 16 17 Console.WriteLine("显示可空类型的值: {0}, {1}, {2}, {3}", num1, num2, num3, num4); 18 Console.WriteLine("一个可空的布尔值: {0}", boolval); 19 Console.ReadLine(); 20 21 } 22 } 23 } 24 //执行结果: 25 //显示可空类型的值: , 45, , 3.14157 26 //一个可空的布尔值:
(三)、Null合并运算符(??)
Null 合并运算符用于定义可空类型和引用类型的默认值。Null 合并运算符为类型转换定义了一个预设值,以防可空类型的值为 Null。Null 合并运算符把操作数类型隐式转换为另一个可空(或不可空)的值类型的操作数的类型。如果第一个操作数的值为 null,则运算符返回第二个操作数的值,否则返回第一个操作数的值。
代码示例:
using System; namespace CalculatorApplication { class NullablesAtShow { static void Main(string[] args) { 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); Console.ReadLine(); } } } //运行结果 //num3 的值: 5.34 //num3 的值: 3.14157
三、数组
数组是一个存储相同类型元素的固定大小的顺序集合。数组是用来存储数据的集合,通常认为数组是一个同一类型变量的集合。
声明数组变量并不是声明 number0、number1、...、number99 一个个单独的变量,而是声明一个就像 numbers 这样的变量,然后使用 numbers[0]、numbers[1]、...、numbers[99] 来表示一个个单独的变量。数组中某个指定的元素是通过索引来访问的。
所有的数组都是由连续的内存位置组成的。最低的地址对应第一个元素,最高的地址对应最后一个元素。
(一)、声明数组
语法:datatype[] arrayName;
初始化:double[] balance = new double[10];
(二)、赋值
1、double[] balance = new double[10]; balance[0] = 4500.0;
2、double[] balance = { 2340.0, 4523.69, 3421.0};
3、int [] marks = new int[5] { 99, 98, 92, 97, 95};
4、int [] marks = new int[] { 99, 98, 92, 97, 95};
5、int [] marks = new int[] { 99, 98, 92, 97, 95};
int[] score = marks;
(三)、访问数组
代码示例:
1 using System; 2 namespace ArrayApplication 3 { 4 class MyArray 5 { 6 static void Main(string[] args) 7 { 8 int [] n = new int[10]; /* n 是一个带有 10 个整数的数组 */ 9 int i,j; 10 11 /* 初始化数组 n 中的元素 */ 12 for ( i = 0; i < 10; i++ ) 13 { 14 n[ i ] = i + 100; 15 } 16 17 /* 输出每个数组元素的值 */ 18 for (j = 0; j < 10; j++ ) 19 { 20 Console.WriteLine("Element[{0}] = {1}", j, n[j]); 21 } 22 Console.ReadKey(); 23 } 24 } 25 } 26 //执行结果 27 //Element[0] = 100 28 //Element[1] = 101 29 //Element[2] = 102 30 //Element[3] = 103 31 //Element[4] = 104 32 //Element[5] = 105 33 //Element[6] = 106 34 //Element[7] = 107 35 //Element[8] = 108 36 //Element[9] = 109
1 using System; 2 namespace ArrayApplication 3 { 4 class MyArray 5 { 6 static void Main(string[] args) 7 { 8 int [] n = new int[10]; /* n 是一个带有 10 个整数的数组 */ 9 10 /* 初始化数组 n 中的元素 */ 11 for ( int i = 0; i < 10; i++ ) 12 { 13 n[i] = i + 100; 14 } 15 16 /* 输出每个数组元素的值 */ 17 foreach (int j in n ) 18 { 19 int i = j-100; 20 Console.WriteLine("Element[{0}] = {1}", i, j); 21 } 22 Console.ReadKey(); 23 } 24 } 25 } 26 //执行结果 27 //Element[0] = 100 28 //Element[1] = 101 29 //Element[2] = 102 30 //Element[3] = 103 31 //Element[4] = 104 32 //Element[5] = 105 33 //Element[6] = 106 34 //Element[7] = 107 35 //Element[8] = 108 36 //Element[9] = 109
(四)、相关细节
在 C# 中,数组是非常重要的,且需要了解更多的细节。下面列出了 C# 程序员必须清楚的一些与数组相关的重要概念:
概念 | 描述 |
---|---|
多维数组 | C# 支持多维数组。多维数组最简单的形式是二维数组。 |
交错数组 | C# 支持交错数组,即数组的数组。 |
传递数组给函数 | 您可以通过指定不带索引的数组名称来给函数传递一个指向数组的指针。 |
参数数组 | 这通常用于传递未知数量的参数给函数。 |
Array 类 | 在 System 命名空间中定义,是所有数组的基类,并提供了各种用于数组的属性和方法。 |
四、字符串
(一)、属性
序号 | 属性名称 & 描述 |
---|---|
1 | Chars 在当前 String 对象中获取 Char 对象的指定位置。 |
2 | Length 在当前的 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 对象中的所有前导空白字符和后置空白字符。 |
(三)、格式化时间
DateTime dt = new DateTime(2017,4,1,13,16,32,108);
string.Format("{0:y yy yyy yyyy}",dt); //17 17 2017 2017
string.Format("{0:M MM MMM MMMM}", dt); //4 04 四月 四月
string.Format("{0:d dd ddd dddd}", dt); //1 01 周六 星期六
string.Format("{0:t tt}", dt); //下 下午
string.Format("{0:H HH}", dt); //13 13
string.Format("{0:h hh}", dt); //1 01
string.Format("{0:m mm}", dt); //16 16
string.Format("{0:s ss}", dt); //32 32
string.Format("{0:F FF FFF FFFF FFFFF FFFFFF FFFFFFF}", dt); //1 1 108 108 108 108 108
string.Format("{0:f ff fff ffff fffff ffffff fffffff}", dt); //1 10 108 1080 10800 108000 1080000
string.Format("{0:z zz zzz}", dt); //+8 +08 +08:00
string.Format("{0:yyyy/MM/dd HH:mm:ss.fff}",dt); //2017/04/01 13:16:32.108
string.Format("{0:yyyy/MM/dd dddd}", dt); //2017/04/01 星期六
string.Format("{0:yyyy/MM/dd dddd tt hh:mm}", dt); //2017/04/01 星期六 下午 01:16
string.Format("{0:yyyyMMdd}", dt); //20170401
string.Format("{0:yyyy-MM-dd HH:mm:ss.fff}", dt); //2017-04-01 13:16:32.108
除去string.Format()可以对日期进行格式化之外,*.ToString()也可以实现相同的效果:
DateTime dt = new DateTime(2017,4,1,13,16,32,108);
dt.ToString("y yy yyy yyyy"); //17 17 2017 2017
dt.ToString("M MM MMM MMMM"); //4 04 四月 四月
dt.ToString("d dd ddd dddd"); //1 01 周六 星期六
dt.ToString("t tt"); //下 下午
dt.ToString("H HH"); //13 13
dt.ToString("h hh"); //1 01
dt.ToString("m mm"); //16 16
dt.ToString("s ss"); //32 32
dt.ToString("F FF FFF FFFF FFFFF FFFFFF FFFFFFF"); //1 1 108 108 108 108 108
dt.ToString("f ff fff ffff fffff ffffff fffffff"); //1 10 108 1080 10800 108000 1080000
dt.ToString("z zz zzz"); //+8 +08 +08:00
dt.ToString("yyyy/MM/dd HH:mm:ss.fff"); //2017/04/01 13:16:32.108
dt.ToString("yyyy/MM/dd dddd"); //2017/04/01 星期六
dt.ToString("yyyy/MM/dd dddd tt hh:mm"); //2017/04/01 星期六 下午 01:16
dt.ToString("yyyyMMdd"); //20170401
dt.ToString("yyyy-MM-dd HH:mm:ss.fff"); //2017-04-01 13:16:32.108
五、结构体
在 C# 中,结构体是值类型数据结构。它使得一个单一变量可以存储各种数据类型的相关数据。struct 关键字用于创建结构体。
特点:
-
-
- 结构可带有方法、字段、索引、属性、运算符方法和事件。
- 结构可定义构造函数,但不能定义析构函数。但是,您不能为结构定义默认的构造函数。默认的构造函数是自动定义的,且不能被改变。
- 与类不同,结构不能继承其他的结构或类。
- 结构不能作为其他结构或类的基础结构。
- 结构可实现一个或多个接口。
- 结构成员不能指定为 abstract、virtual 或 protected。
- 当您使用 New 操作符创建一个结构对象时,会调用适当的构造函数来创建结构。与类不同,结构可以不使用 New 操作符即可被实例化。
- 如果不使用 New 操作符,只有在所有的字段都被初始化之后,字段才被赋值,对象才被使用。
-
与类的比较:
-
-
- 类是引用类型,结构是值类型。
- 结构不支持继承。
- 结构不能声明默认的构造函数。
-
示例代码:
1 using System; 2 using System.Text; 3 4 struct Books 5 { 6 private string title; 7 private string author; 8 private string subject; 9 private int book_id; 10 public void getValues(string t, string a, string s, int id) 11 { 12 title = t; 13 author = a; 14 subject = s; 15 book_id =id; 16 } 17 public void display() 18 { 19 Console.WriteLine("Title : {0}", title); 20 Console.WriteLine("Author : {0}", author); 21 Console.WriteLine("Subject : {0}", subject); 22 Console.WriteLine("Book_id :{0}", book_id); 23 } 24 25 }; 26 27 public class testStructure 28 { 29 public static void Main(string[] args) 30 { 31 32 Books Book1 = new Books(); /* 声明 Book1,类型为 Book */ 33 Books Book2 = new Books(); /* 声明 Book2,类型为 Book */ 34 35 /* book 1 详述 */ 36 Book1.getValues("C Programming", 37 "Nuha Ali", "C Programming Tutorial",6495407); 38 39 /* book 2 详述 */ 40 Book2.getValues("Telecom Billing", 41 "Zara Ali", "Telecom Billing Tutorial", 6495700); 42 43 /* 打印 Book1 信息 */ 44 Book1.display(); 45 46 /* 打印 Book2 信息 */ 47 Book2.display(); 48 49 Console.ReadKey(); 50 51 } 52 } 53 //执行结果 54 //Title : C Programming 55 //Author : Nuha Ali 56 //Subject : C Programming Tutorial 57 //Book_id : 6495407 58 //Title : Telecom Billing 59 //Author : Zara Ali 60 //Subject : Telecom Billing Tutorial 61 //Book_id : 6495700
六、枚举
枚举是一组命名整型常量。枚举类型是使用 enum 关键字声明的。
C# 枚举是值类型。换句话说,枚举包含自己的值,且不能继承或传递继承。
枚举列表中的每个符号代表一个整数值,一个比它前面的符号大的整数值。默认情况下,第一个枚举符号的值是 0,当然,我们也可以自定义每个符号的值。
可参考:http://www.cnblogs.com/lina-chu/p/8391325.html
示例代码:
1 using System; 2 namespace EnumApplication 3 { 4 class EnumProgram 5 { 6 enum Days { 7 Mon=71, 8 tue=61, 9 Wed=51, 10 thu=41, 11 Fri=51, 12 Sat=61, 13 Sun=71 14 }; 15 16 static void Main(string[] args) 17 { 18 int WeekdayStart = (int)Days.Mon; 19 int WeekdayEnd = (int)Days.Fri; 20 Console.WriteLine("Monday: {0}", WeekdayStart); 21 Console.WriteLine("Friday: {0}", WeekdayEnd); 22 Console.ReadKey(); 23 } 24 } 25 } 26 //执行结果 27 //Monday: 71 28 //Friday: 51
七、下期预告 - https://www.cnblogs.com/liu-jinxin/p/10831189.html
->类
->继承
->封装
->多态
参考文献:
1、https://www.runoob.com/csharp/csharp-variables.html
根据w3school自我温习一下c#基础,分享给大家。