C sharp (C#)
1 C#准备知识
1.1 启动 VS 命令
devenv - (development envirnment)
1.2 .Net Framework 编写应用程序的过程
程序代码 => CIL(存放在程序集合中)=>(JIT编译器)本机代码 native code => CLR托管 EXE DLL
1.3 第一个控制台程序
namespace _1第一个控制台程序
{
class Program
{
static void Main(string[] args) {
Console.WriteLine("Hello World!!!");
Console.ReadKey(); // 等待用户输入,常用来对程序界面进行停留。
}
}
}
注:Console.WriteLine() 可以用 {索引号} 占位符输出变量,如:
Console.WriteLine("您好:{0}您的年龄是{1}是个{2}生", name, age, sex);
1.4 C#中三种注释符
- 单行注释——
//注释内容 - 多行注释——
/*注释内容*/ - 文档注释(在方法或类的上一行输入)——
/// 注释内容 ///
1.5 VS常用快捷键
Ctrl+Shift+N:新建项目;
Ctrl+K+D: 快速对齐代码(格式化代码);
Ctrl+Z:撤销;
Ctrl+S:保存;
Ctrl+J:快速弹出智能提示;
Shift+End:快速选中光标到行尾的内容;
Shift+Home:快速选中光标到行首的内容;
Ctrl+K+C:注释所选代码;
Ctrl+K+U:取消对所选代码的注释;
F1:转到帮助文档;
1.6 第一个桌面程序
新建 WPF Application(或WindowsForm)
// MainWindow.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace HelloWorldWPF
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Hello World!!!", "第一个 WPF 程序");
}
}
}
// MainWindow.xaml 样式文件
<Window x:Class="HelloWorldWPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:HelloWorldWPF"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Button Width="100" Height="50" Background="#FF0056FF" Foreground="White" FontSize="16" FontWeight="Bold" BorderThickness="0,0,0,0" Click="Button_Click">测试</Button>
</Grid>
</Window>
1.7 程序结构
using System; // 引用命名空间
namespace _1第一个控制台程序 // 命名空间或项目名称
{
class Program // Program 类
{
static void Main(string[] args) // static-静态,void-无返回值,Main 函数也是我们程序的起点
{
Console.WriteLine("Hello World!!!");
}
}
}
2 C# 基础语法
2.1 C# 程序结构
.Sln:解决方案文件;
.csproj:项目文件;
.cs:类文件;
解决方案文件和项目文件以及类文件之间的关系:解决方案文件包含项目文件,项目文件包含类文件。
解决方案下可包含多个项目,在解决方案上右键选择属性,可以设置默认运行的项目。
2.2 命名空间及标识符、关键字
2.2.1 命名空间
命名空间(namespace)是 .NET 中提供应用程序代码容器的方式,用来唯一地表示代码及其内容。 创建命名空间的关键字是 namespace。 命名空间是以“层”形式存在的,如有多层,则以“.”分开。 如果命名空间名称太长,可以给命名空间一个别名,语法为:using 别名=命名空间,用法如下:
using CW = System.Console;
namespace _1第一个控制台程序
{
class Program
{
static void Main(string[] args)
{
CW.WriteLine("Hello World!!!");
}
}
}
2.2.2 标识符
标识符是编程人员为变量、常量、数据类型、方法、函数、属性、类、程序等定义的名称。
例如:string username 中的 username 为标识符。
注意:
- 标识符只能由大写字母,小写字母,数字和下划线组成;
- 标识符必须以字符或者下划线开头;
- C 语言是区分大小写的,
username和Username是不同的标识符; - 如果在 C# 中需要将关键字作为标识符就要在前面加上
@。
2.2.3 关键字
对于 C# 编译器而言,具有特定含义的名称,比如程序中的 using,class,static,void等,关键字不可用作标识符。
3 变量、常量与数据类型
3.1 变量
声明变量:数据类型 变量名;。
一次性声明多个相同类型的变量可用逗号隔开:string zsName,IsName;
变量一定要先声明,再赋值,才能使用。
变量的命名规则:
-
必须以字母、下划线或
@符号开头,不能以数字开头; -
后面可以跟任意字母、数字或下划线。
-
注意:
- 不能与 C# 中的关键字重复;
- 在 C# 中,大小写是敏感的;
- 同一个变量名不可重复定义;
- 定义变量时,变量名要有意义;
- 英文字母缩写全用大写;
3.2 常量
常量是指在程序运行时不能改变的数据。
声明常量:const 数据类型 常量名称 = 常量值;
注意:一定要给常量赋值,赋值后不给改变。
3.3 变量、常量作用域
一般确定作用域有以下规则:
- 局部变量存在于声明该变量的块语句或方法的大括号内。
- 在
for、while、foreach等循环语句中声明的变量,只存在于该循环体内。
总之,变量作用域为包含它的大括号。
3.3 @作用
-
忽略转义字符
// 不使用 @ string fileName = "D:\51zxw\text.txt"; // 使用 @ string fileName = @"D:\51zxw\text.txt"; -
让字符串跨行(代替 +)
// 不使用 @ string SQLStr = "SELECT * FROM HumanResources.Employee AS e" + " INNER.JOIN Person.Contact AS c" + " ON e.ContactID = c.ContactID" + " ORDER BY c.LastName"; // 使用 @ string SQLStr = @"SELECT * FROM HumanResources.Employee AS e INNER.JOIN Person.Contact AS c ON e.ContactID = c.ContactID ORDER BY c.LastName"; -
在标识符中的用法
C# 不允许使用关键字作为标识符(类名、变量名、方法名、表空间名等)使用,但如果加上@之后就可以了,例如:
@namespace或@class。
3.4 数据类型
数据类型是表示具有多种相同特征的一组数据。
C# 预定义的数据类型包括值类型和引用类型。
3.4.1 值类型
值类型是在栈中操作。
值类型直接保存其值,如 int (整型)就属于值类型,如声明了一个整型变量,并给它赋予另一个整型变量的值,则在内存事先复制一个整型变量的值,然后将其赋予刚声明的整型变量,这时内存中就会有两个整型值。
值类型包括数值类型、布尔类型、字符类型等。
-
整数类型
数据类型 说明 取值范围 对应于System程序集中的结构 sbyte 有符号3位整数 -128 ~ 127 SByte byte 无符号8位整数 0 ~ 255 Byte short 有符号16位整数 -32768 ~ 32767 Int16 ushort 无符号16位整数 0 ~ 65534 UInit16 Int 有符号32位整数 -2147489648 ~ 2147483647 Int32 uint 无符号32位整数 0 ~ 42994967295 UInit32 long 有符号64位整数 -2^63 ~ 2^63 Int64 ulong 无符号64位整数 0 ~ 2^64 UInt64 -
浮点类型
数据类型 说明 取值范围 float 32位单精度实数 1.510^(-45) ~ 3.410^38 double 64位双精度实数 5.010^(-324) ~ 1.710^(308) demcimal 128位十进制实数 1.010^(-28) ~ 7.910^28 -
布尔类型
只用 true、false 两个值,关键字为 bool,在计算机中占4个字节(4B),即32位存储空间,但不能用0和1代替。
-
字符类型
即保存单个字符的值,字符类型的关键字是char,每个字符对象与Unicode字符集的字符对应,char类型的字符变量是用单引号括起来的,如果把字符放在双引号中,编译器会将其认为字符串。
3.4.2 引用类型
引用类型在堆中分配存储单元。
引用类型的变量在内存中是直接保存其值的引用。C# 中大多数复杂数据类型都是引用类型,例如类就是引用类型。
在 C# 预定义的类型中,属于引用类型的有对象(object)类型和字符串(string)类型两种。
-
object 类型:是所有其他类型的基类型,所以可把任何类型的值赋给它。
-
String 类型:在 C# 中,字符串(string)类型是用一对双引号引起来的字符。注意:
- 字符串的不可变形:当个一个字符串重新赋值后,老值并没有销毁,而是重新开辟一块空间存储新值,当程序结束后,GC 扫描整个内存,如果发现有的空间没有被指向,则立即把它销毁。
- 字符串可以看做是 char 类型的一个只读数组。
3.4.3 值类型与引用类型的区别
- 值类型和引用类型在内存上存储的地方不一样。
- 在传递值类型和传递引用类型的时候,传递的方式不一样。
值类型我们称之为值传递,引用类型我们称之为引用传递。
3.4.4 类型转换
- 使用
Convert,如将字符串类型转为 int 类型:
int time = Convert.ToInt32(Console.ReadLine());
int.Parse(字符串)
4 运算符
4.1 布尔运算符
| 运算符 | 类别 | 示例表达式 | 结果 | ||||
|---|---|---|---|---|---|---|---|
| && | 二元 | var3 = var1 && var2 | 同时为 true 时结果为 true | ||||
| 二元 | var3 = var1 | var2 | 一个为 true 时结果为 true | ||||
| ! | 一元 | var3 = !var1 | var1 为 true 时结果为 false | ||||
| 二元 | var3 = var1 ^ var2 | 有且只有一个为 true 时结果为 true | |||||
| & | 二元 | var3 = var1 & var2 | 同时为 true 结果为 true | ||||
| 二元 | var3 = var1 | var2 | 一个为 true 时结果为 true |
4.2 位运算符
位(bit):在计算机中存储所有数据都采用二进制。
- 1Byte = 8bit(1字节 = 8位)
- 1K = 1024Byte
- 1M = 1024K
- 1G = 1024M
- 1T = 1024G
| 运算符 | 类别 | 示例表达式 | 结果 | |
|---|---|---|---|---|
| ~ (按位取反) | 一元 | / | / | |
| & (与) | 二元 | / | / | |
| (或) | 二元 | / | / | |
| ^ (亦或) | 二元 | / | / | |
| << (左移) | 二元 | var3 = var1 << var2 | var1 向左移动 var2 位,将所得值赋值给 var3 | |
| >> (右移) | 二元 | var3 = var1 >> var2 | var1 向右移动 var2 位,将所得值赋给 var3 |
注意:
- 大多数代码中都不使用这些运算符,主要用于高度优化的代码,常用于驱动程序或系统代码。
- << 一位,相当于乘以 2
-
一位,相当于除以 2,然后去除非整数部分
4.3 其他运算符
-
字符串连接运算符
+:将两个字符串连接在一起组成一个新的字符串,如string str1 = "my name is"; string str2 = " snowskywalker"; string str3 = str1 + str2; // str3 = "my name is snowskywalker"; -
is运算符:用于动态检查对象的运行时类型是否与给定类型兼容。如string str = "my name is"; bool b = str is string; Console.WriteLine(b); // 输出 True
4.4 运算符的优先级
| 优先级 | 类别 | 运算符 | ||
|---|---|---|---|---|
| 1 | 基本 | (x) .y .(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 | 赋值 | = += -= *= /= <<= >>= ^= | = |
优先级数越小,优先级别也就越高;
当操作相同优先级的两个运算符时,运算符的执行顺序遵循如下原则:
1. 除了复制运算符外,所有的二元运算符执行顺序都是“从左向右”;
2. 赋值运算符和条件运算符(三元运算符)都是按照“从左向右”的顺序执行;
当执行多个运算符时,在运算符的优先级不确定时,为了提高程序的可读性和清晰度,可使用括号进行顺序控制。
5 流程控制
5.1 分支语句
分支语句是指根据实际情况决定逻辑路径的代码。
-
if
if(判断条件表达式) { // 表达式为 true 时执行 } else { // 表达式为 false 时执行 } -
switch
switch(表达式) { case 常量表达式: 条件语句; case 常量表达式: 条件语句; case 常量表达式: 条件语句; default: 条件语句; } -
? :
条件判断表达式 ? 成立时执行的语句 : 不成立时的语句;
总结:
- if 语句适合判断一些连续的值;
- switch 语句适合判断一些离散的值,每个 case 语句之后都必须有 break 语句;
- 三元运算符适合简单的赋值语句,可读性较差;
5.2 迭代语句
迭代语句是指在程序中重复执行,直到满足指定条件才停止的一段代码。
-
while
while(条件表达式) { // 循环体语句 } -
do...while
循环体语句至少执行一次,即使 while 条件语句不成立。
do { // 循环体语句 }while(判断语句) -
for
for(初始条件;判断条件;循环条件) { // 循环体语句 }注意:初始条件,判断条件和循环条件都能省略,但是分号不能省略。
-
foreach
foreach(类型 变量 in 集合) { // 代码体 }补充:string 类型可以看成是 char 类型的一个集合。
5.3 跳转语句
跳转语句是程序运行到某个位置时,可以调到程序中另一行代码的语句。
-
break
break 语句的作用:
- 在 switch 语句中用于从 case 语句中跳出,结束 switch 分支语句;
- 用于跳出迭代语句,结束当前循环。
-
continue
意义:用于停止当前的迭代语句,结束本次循环,break 是直接结束循环。
使用:
continue; -
return
return 语句使用时一般有两种格式:
-
return; -
return 表达式;
说明:return 语句只能出现在方法当中,当调用方法时,执行到 return 语句时,直接跳转到 Main() 函数。
-
-
goto
goto 标识符;标识符标识程序位置的方法,当程序执行到 goto 语句时,程序会直接跳转到标识符所标识的程序位置,并继续执行代码。
goto 语句会使代码的易读性下降,在编写程序时尽量少用 goto 语句。
6 字符与字符串
6.1 字符及转义字符
6.1.1 字符
char 类结构表示 unicode 字符。
Unicode 标准使用称为码位的唯一的21位标量数字标识每个 Unicode 字符,并定义 UTF-16 编码格式,这一格式指定如何将码位编码为一个或多个16位值的序列,每个16位值的范围为十六进制的 0x0000 ~ 0xFFFF,并存储在 Char 结构中。Char 对象的值是其16位数字(序号)值。
定义格式:
char 变量名 = '初始值';
char 类常用方法:
| 方法 | 作用 |
|---|---|
| IsLetter | 是否是字母 |
| IsDigit | 是否是数字 |
| IsLetterOrDigit | 是否是数字或字母 |
| IsLower | 是否是小写 |
| IsUpper | 是否是大写 |
| IsPunctuation | 是否是标点 |
| IsSeparator | 分隔符 |
| IsWhiteSpace | 是否是空格 |
| ToLower | 转化为小写 |
| ToUpper | 转化为大写 |
例如:
char.IsLetter('&'); // False
6.1.2 转义字符
| 转义符 | 作用 |
|---|---|
| ' | 单引号 |
| " | 双引号 |
| \ | 反斜杠 |
| \0 | 空字符 |
| \a | alert 感叹号 |
| \b | 退格 |
| \f | 换页 |
| \n | 新行 |
| \r | 回车 |
| \t | 水平 tab |
| \v | 竖直 tab |
6.2 字符串
字符串是由零个或多个字符组成的有限序列,是 System.String 类的一个引用类型,但与其他引用类型不同的是,C# 将字符串视为一个基本类型,可以声明为一个变量,并为其赋值。
声明方式:
string 变量名 = "初始值";
注意:string 类型变量可以看成是 char 变量的只读数组。
6.2.1 字符集与字符编码
字符集:是一个系统支持的所有抽象字符的集合。
字符编码:是一套法则,使用该法则能够对自然语言的字符的一个集合(如字母表或音节表),与其他东西的一个集合(如号码或电脉冲)进行配对。
常见字符集名称:ASCII字符集、GB2312字符集、BIG5字符集、GB18030字符集、Unicode字符集、UTF-8等。
计算机要准确的处理各种字符集文字,需要进行字符编码,以便计算机能够识别和存储各种文字。
6.2.2 字符串的大小写转换
大写:ToUpper
小写:ToLower
如:
string name = "Jack";
Console.WriteLine(name.ToUpper()) ;
Console.WriteLine(name.ToLower()) ;
6.2.3 字符串的比较
比较方法:
-
字符串1 == 字符串2例:
string name1 = "Jack"; string name2 = "JACK"; Console.WriteLine(name1 == name2) ; -
string.Equals(字符串1,字符串2)例:
string name1 = "Jack"; string name2 = "JACK"; Console.WriteLine(string.Equals(name1, name2)); -
string.Compare(字符串1,字符串2,布尔值)例:
string name1 = "Jack"; string name2 = "JACK"; Console.WriteLine(string.Compare(name1,name2,true));返回一个整数:
返回值 结果 小于0 字符串1 < 字符串2 等于0 字符串1 = 字符串2 大于0 字符串1 > 字符串2 布尔值为 true 时,忽略大小写进行比较。
-
字符串1.CompareTo(字符串2)例:
string name1 = "Jack"; string name2 = "JACK"; Console.WriteLine(name1.CompareTo(name2));返回一个整数:
返回值 结果 小于0 字符串1 < 字符串2 等于0 字符串1 = 字符串2 大于0 字符串1 > 字符串2,或字符串2是null引用
6.2.4 字符串的格式化
string.Format(要转换的格式,格式化的对象);
string.Format(要转换的格式,格式化的对象一,格式化的对象二)
例:
string result = string.Format("{0:C},{1:C}", 20,40);
Console.WriteLine(result); // 输出 ¥20.00,¥40.00
常用数值格式符如下:
| 方法 | 适用类型 | 含义 |
|---|---|---|
| C | 数字类型 | 专用场合的货币值 |
| D | 只用于整数类型 | 一般整数 |
| E | 数字类型 | 科学技术法 |
| F | 数字类型 | 小数点后的位数固定 |
| G | 数字类型 | 一般整数 |
| N | 数字类型 | 通用场合数字格式 |
| P | 数字类型 | 百分数 |
| X | 只用于整数类型 | 十六进制格式 |
6.2.5 字符串的截取
-
字符串1.Substring(整数n)将字符串1前n个长度的字符串截取掉,保留后面的字符串。
-
字符串1.Substring(整数n,整数m)保留从字符串1第n个长度开始数m个长度的字符串。
6.2.6 字符串的分割
通过 字符串1.Split(字符或字符数组)分割字符串,返回值为一个字符串数组。
如:
string str = "PHP,是世界上-最好的语言!";
string[] strArr = str.Split(new char[] { ',', '-'});
foreach (string str2 in strArr)
{
Console.WriteLine(str2+'\n');
}
6.2.7 字符串的合并
-
+字符串3 = 字符串1 + 字符串2 -
Concatstring Concat(字符串1,字符串2,字符串3,...,字符串n) -
Joinstring.Join(合并后的分隔符,字符串数组);
6.2.8 字符串的插入与填充
-
插入
字符串.Insert(插入位置,插入子串) -
填充
str.PadRight(int: totalWidth,char?: paddingChar):stringstr.PadLeft(int: totalWidth,char?: paddingChar):stringstr:源字符串;
totalWidth:总长度;
char?:填充的字符,默认为空格;
通过添加指定的重复字符填充字符串。
例如:
string str = "我要";
Console.WriteLine(str.PadRight(10,'旺')); // 输出 我要旺旺旺旺旺旺旺旺
6.2.9 字符串的删除
删除是通过 Remove 来实现的。
str.Remove(int: startIndex,int?: count)
startIndex:删除的开始字符索引。
count?:从删除的开始字符索引往后数的数量。
从开始位置数到移出数位置的字符删除,移出数可不指定,如果指定,则将开始位置之后所有字符删除。
例如:
string str = "PHP不是世界上最好的语言";
Console.WriteLine(str.Remove(3,1)); // 输出 PHP是世界上最好的语言
6.2.10 字符串修剪
修剪即为删除字符串头尾出现的某些字符,C# 有三个修剪字符串的方法:
- Trim():删除字符串首部和尾部的空格。
- TrimStart():删除字符串头部的空格。
- TrimeEnd():删除字符串尾部的空格。
以上三种方法均可带参数,即为删除指定位置的指定字符。如:
string str = "@wkaals#";
Console.WriteLine(str.Trim("@","#"); // 输出 wkaals
// 等价于
Console.WriteLine(str.Trim("@#".ToCharArray())); // 输出 wkaals
6.2.11 字符串的复制
-
string.Copy(string:str1):string;str1:要复制的字符串
string str1 = "要复制的字符串"; string str2 = string.Copy(str1); Console.WriteLine(str2); // 输出 要复制的字符串 -
str.CopyTo(int:sourceIndex,char[]:destination,int:destinationIndex,int:count):void;str:要复制的字符串;
sourceIndex:要复制字符的起始位置;
destination:目标字符数组;
destinationIndex:目标数组中的开始存放位置;
count:要复制的字符个数;
例如:
string str1 = "要复制的字符串"; char[] targetArr = new char[20]; str1.CopyTo(2, targetArr, 1, 3); Console.WriteLine(targetArr); // 输出 制的字