C# 是一种面向对象的编程语言。在面向对象的程序设计方法中,程序由各种相互交互的对象组成。
C#与.NET框架
.NET框架是微软公司推出的一个编程平台。C#就其本身而言是一种语言,尽管它是用于生成面向.NET环境的代码,但它本身不是.NET的一部分。
命名空间
C#程序是利用命名空间组织起来的。
using System;
using N1; //使用using指令引入命名空间N1
namespace Test02
{
class Program
{
static void Main(string[] args)
{
A oa = new A(); //实例化N1中的类A
oa.Myls(); //调用类A中的Myls方法
}
}
}
namespace N1 //建立命名空间N1
{
class A //在命名空间N1中声明一个类A
{
public void Myls()
{
Console.WriteLine("用一生来爱你"); //输出字符串
Console.ReadLine();
}
}
}
using 关键字
在任何 C# 程序中的第一条语句都是:
using System;
using 关键字用于在程序中包含命名空间。一个程序可以包含多个 using 语句。
class 关键字
class 关键字用于声明一个类。
C# 类(Class)
当你定义一个类时,你定义了一个数据类型的蓝图。这实际上并没有定义任何的数据,但它定义了类的名称意味着什么,也就是说,类的对象由什么组成及在这个对象上可执行什么操作。对象是类的实例。构成类的方法和变量称为类的成员。
类的定义
类的定义是以关键字 class 开始,后跟类的名称。类的主体,包含在一对花括号内。
<access specifier> class class_name
{
// member variables
<access specifier> <data type> variable1;
// member methods
<access specifier> <return type> method1(parameter_list)
{
// method body
}
}
Main方法
Main方法是程序的入口点,C#程序中必须包含一个Main方法,在该方法中可以创建对象和调用其他方法,一个C#程序中只能有一个Main方法,并且在C#中所有的Main方法都必须是静态的。
可以用3个修饰符修饰Main方法,分别是public、static和void
public:说明Main方法是共有的,在类的外面也是可以调用整个方法。
static:说明方法是一个静态方法,即整个方法属于类的本身,而不是这个类的特定对象。调用静态方法不能使用类的实例化对象,必须直接使用类名来调用。
void:此修饰符说明方法无返回值。
标识符及关键字
标识符只能由数字,字母和下划线组成
标识符必须以字母或者下划线开头
标识符不能是关键字
程序编写规范
代码书写规则
尽量使用接口,然后使用类实现接口,以提高程序的灵活性。
一行不要超过80个字符。
尽量不要手工更改计算机生成的代码,若必须要改,一定要改成和计算机生成的代码风格一样。
关键的语句(包括声明关键的变量)必须要写注释。
建议局部变量在最接近使用它的地方声明。
不要使用goto系列语句,除非是用在跳出深层循环时。
避免写超过5个参数的方法,如果传递多个参数,则使用结构。
避免书写代码量过大的try…catch模块
避免在同一个文件中放置多个类。
生成和构建一个长的字符串时,一定要使用StringBuilder类型,而不用string类型。
switch语句一定要有default语句来处理意外情况。
对于if语句,应该使用一对“{}”把语句块包含起来
尽量不使用this关键字引用
命名规范
用Pascal规则来命名方法和类型,Pascal的命名规则是第一个字母必须大写,并且后面的连接词的第一个字母均为大写。
声明一个字符串变量和创建一个公共方法
如:
string strUserName;//声明一个字符串变量strUserName
public void addUser(string strUserld,byte[] byPassword); //创建一个具有两个参数的公共方法
所有的成品变量前加前缀“_”
在公共类DataBase中声明一个私有成员变量_connectionString。
代码如下:
public class DataBase //创建一个公共类
{
private string _connectionString; //声明一个私有成员变量
}
接口的名称加前缀“I”.
public interface Iconvertible //声明一个公共接口Iconvertible
{
byte ToByte(); //声明一个byte类型的方法
}
方法的命名,一般将其命名为动宾短语。
public class File //创建一个公共类
{
public void CreateFile(string filePath) //创建一个CreateFile方法
{
}
public void GetPath(string path) //创建一个GetPath方法
{
}
}
所有的成员变量声明在类的顶端,用一个换行把它和方法分开。
public class Product //创建一个公共类
{
private string _productId; //在类的顶端声明变量
private string _productName; //在类的顶端声明变量
public void AddProduct(string productId, string productName) //创建一个公共方法
{
}
}
用有意义的名字命名命名空间,如公司名,产品名。
namespace Zivsoft //公司命名
{
}
namespace ERP //产品命名
{
}
变量的基本概念
变量本身被用来存储特定类型的数据,可以根据需要随时改变变量中所存储的数据值。变量具有名称、类型和值。
变量的类型
值类型
(1.整数类型 2.浮点类型 3.布尔类型)
引用类型
引用类型是构建C#应用程序的主要对象类型数据。
具有以下特征 :
必须在托管堆中为引用类型变量分配内存。
必须使用new关键字来创建引用类型变量
在托管堆中分配的每个对象都有与之相关联的附加成员,这些成员必须被初始化。
引用类型变量是由垃圾回收机制来管理的。
多个引用类型变量可以引用同一对象,这种情形下,对一个变量的操作会影响另一个变量所引用的同一对象。
引用类型被赋值前的值都是null
所有被称为“类”的都是引用类型,主要包括类、接口、数组和委托。
枚举类型 (Enum)
枚举是一组命名整型常量。枚举类型是使用 enum 关键字声明的。
C# 枚举是值类型。换句话说,枚举包含自己的值,且不能继承或传递继承。
枚举类型是一种独特的值类型,它用于声明一组具有相同性质的常量。
其中,
enum_name 指定枚举的类型名称。
enumeration list 是一个用逗号分隔的标识符列表。
枚举列表中的每个符号代表一个整数值,一个比它前面的符号大的整数值。默认情况下,第一个枚举符号的值是 0.例如:
enum <enum_name>
{
enumeration list
};
示例1
enum Days { Sun, Mon, tue, Wed, thu, Fri, Sat };
class Program
{
enum MyDate
{
Sun = 0, //设置枚举值名称Sun,枚举值为0
Mon = 1, //设置枚举值名称Mon,枚举值为1
Tue = 2, //设置枚举值名称Tue,枚举值为2
Wed = 3, //设置枚举值名称Wed,枚举值为3
Thi = 4, //设置枚举值名称Tue,枚举值为4
Fri = 5, //设置枚举值名称Tue,枚举值为5
Sat = 6, //设置枚举值名称Tue,枚举值为6
}
static void Main(string[] args)
{
int k = (int)DateTime.Now.DayOfWeek; //获取代表星期几的返回值
switch (k)
{
//如果k等于枚举变量MyDate中的Sun的枚举值,则输出今天是星期日
case (int)MyDate.Sun: Console.WriteLine("今天是星期日"); break;
//如果k等于枚举变量MyDate中的Mon的枚举值,则输出今天是星期一
case (int)MyDate.Mon: Console.WriteLine("今天是星期一"); break;
//如果k等于枚举变量MyDate中的Tue的枚举值,则输出今天是星期二
case (int)MyDate.Tue: Console.WriteLine("今天是星期二"); break;
//如果k等于枚举变量MyDate中的Wed的枚举值,则输出今天是星期三
case (int)MyDate.Wed: Console.WriteLine("今天是星期三"); break;
//如果k等于枚举变量MyDate中的Thi的枚举值,则输出今天是星期四
case (int)MyDate.Thi: Console.WriteLine("今天是星期四"); break;
//如果k等于枚举变量MyDate中的Fri的枚举值,则输出今天是星期五
case (int)MyDate.Fri: Console.WriteLine("今天是星期五"); break;
//如果k等于枚举变量MyDate中的Sat的枚举值,则输出今天是星期六
case (int)MyDate.Sat: Console.WriteLine("今天是星期六"); break;
}
Console.ReadLine();
}
}
程序运行的结果为“今天是星期一”。当前日期为2021/11/01
示例2
下面的实例演示了枚举变量的用法:
using System;
public class EnumTest
{
enum Day { Sun, Mon, Tue, Wed, Thu, Fri, Sat };
static void Main()
{
int x = (int)Day.Sun;
int y = (int)Day.Fri;
Console.WriteLine("Sun = {0}", x);
Console.WriteLine("Fri = {0}", y);
}
}
当上面的代码被编译和执行时,它会产生下列结果:
Sun = 0
Fri = 5
类型转换
类型转换从根本上说是类型铸造,或者说是把数据从一种类型转换为另一种类型。在 C# 中,类型铸造有两种形式:
隐式类型转换 - 这些转换是 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();
}
}
}
当上面的代码被编译和执行时,它会产生下列结果: 5673
装箱和拆箱
将值类型转换为引用类型的过程叫做装箱,相反,将引用类型转换为值类型的过程叫做拆箱。
(1)装箱
装箱允许将值类型隐式转换成引用类型。
class packing
{
static void Main(string[] args)
{
int i = 2008; //声明一个int类型变量i,并初始化为2008
object obj = i; //声明一个object类型obj,其初始化值为i
Console.WriteLine("1.i的值为{0},装箱之后的对象为{1}",i,obj);
i = 927; //重新将i赋值为927
Console.WriteLine("2.i的值为{0},装箱之后的对象为{1}",i,obj);
Console.ReadLine();
}
运行结果为:
1.i的值为2008,装箱之后的对象为2008
2.i的值为927,装箱之后的对象为2008
(2)拆箱
拆箱允许将引用类型显示转换为值类型
class packing
{
static void Main(string[] args)
{
int i = 112; //声明一个int类型变量i,并初始化为112
object obj = i; //执行装箱操作
Console.WriteLine("装箱操作:值为{0},装箱之后的对象为{1}", i, obj);
int j = (int)obj; //执行拆箱操作
Console.WriteLine("拆箱操作:装箱对象为{0},值为{1}", obj,j);
Console.ReadLine();
}
}
运行结果为:
装箱操作:值为112,装箱之后的对象为112
拆箱操作:装箱对象为112, 值为112
变量操作
声明变量
声明变量就是指定变量的名称和类型,变量的声明非常重要,未经声明的变量本身并不合法,也因此没有办法在程序中使用。
int LS; //声明一个整形变量
string Str1,Str2,Str3; //同时声明3个字符型变量
int a=927; //初始化整型变量a
string x=“用一生下载你”, y="用一生爱你",z="一生所爱"; //初始化字符型变量x、y、z
变量的作用域
变量的作用域就是可以访问该变量的代码区域。一般情况下,可以通过以下规则确定变量的作用域。
只要字段所属的类在某个作用域内,其字段也在该作用域内。
局部变量存在于表示声明该变量的块语句或方法结束的封闭花括号之前的作用域内。
在for、while或类似语句中声明的局部变量存在于该循环体内。
class packing
{
static void Main(string[] args)
{
//调用for语句循环输出数字
for (int i = 0; i <= 20; i++) //for循环内的局部变量i
{
Console.WriteLine(i.ToString());//输出0~20的数字
}
Console.ReadLine();
}
}
变量的赋值
在C#中,使用赋值运算符“=”(等号)来给变量赋值,将等号右边的值赋给左边的变量。
int sum; //声明一个变量
sum =2008; //使用赋值运算符“=”给变量赋值
int sum,num; //声明两个变量
sum = 927; //给变量sum赋值为927
num=sum; //将变量sum赋值给变量num
常量
常量就是其值固定不变的量,而且常量的值在编译时就已经确定了。常量的类型只能为下列类型之一:sbyte,byte,short,ushort,int,uint,long,ulong,char,float,double,decimal,bool,string 等。
表达式与运算符
表达式
表达式是由运算符和操作数组成的。运算符设置对操作数进行什么样的运算。
class packing
{
static void Main(string[] args)
{
int i = 927; //表明一个int类型的变量i并初始化为927
int j = 112; //表明一个int类型的变量j并初始化为112
Console.WriteLine(Math.Sin(i*i+j*j)); //表达式作为参数输出
Console.ReadLine();
}
}
运行结果为 - 0.599423085852245
运算符
运算符针对操作数进行运算,同时产生运算结果。
算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符及其他运算符。
算术运算符
+,-,*,/和%运算符都称为算术运算符,分别用于进行加、减、乘、除和模(求余数)运算。
下表显示了 C# 支持的所有算术运算符。假设变量 A 的值为 10,变量 B 的值为 20,则:
| 运算符 | 描述 | 实例 |
|---|---|---|
| + | 把两个操作数相加 | A + B 将得到 30 |
| - | 从第一个操作数中减去第二个操作数 | A - B 将得到 -10 |
| * | 把两个操作数相乘 | A * B 将得到 200 |
| / | 分子除以分母 | B / A 将得到 2 |
| % | 取模运算符,整除后的余数 | B % A 将得到 0 |
| ++ | 自增运算符,整数值增加 1 | A++ 将得到 11 |
| – | 自减运算符,整数值减少 1 | A-- 将得到 9 |
1.加法运算符
class packing
{
static void Main(string[] args)
{
int i = 927; //表明一个int类型的变量i并初始化为927
int j = 112; //表明一个int类型的变量j并初始化为112
int M2;
M2 = i + j;
Console.WriteLine(M2.ToString()); //M2的值为i+j的值相加
Console.ReadLine();
}
}
运行结果为 :1039
2.减法运算符 — 3.乘法运算符 * 4.除法运算符 /
5.求余运算符 %
class packing
{
static void Main(string[] args)
{
int i = 55; //表明一个int类型的变量i并初始化为55
int j = 10; //表明一个int类型的变量j并初始化为10
int M2;
M2 = i % j;
Console.WriteLine(M2.ToString()); //M2的值为i+j的值求余
Console.ReadLine();
}
}
程序运行结果为 : 5
赋值运算符
赋值运算符为变量、属性、事件等元素赋新值。
class packing
{
static void Main(string[] args)
{
int i = 55; //表明一个int类型的变量i并初始化为55
i += 112; //使用加赋值运算符
Console.WriteLine("最后i的值为:{0}",i); //输出最后变量i的值
Console.ReadLine();
}
}
程序运行结果为 : 最后i的值为:167
关系运算符
下表显示了 C# 支持的所有关系运算符。假设变量 A 的值为 10,变量 B 的值为 20,则:
| 运算符 | 描述 | 实例 |
|---|---|---|
| == | 检查两个操作数的值是否相等,如果相等则条件为真。 | (A == B) 不为真。 |
| != | 检查两个操作数的值是否相等,如果不相等则条件为真。。 | (A != B) 为真。 |
| > | 检查左操作数的值是否大于右操作数的值,如果是则条件为真。 | (A > B) 不为真。 |
| < | 检查左操作数的值是否小于右操作数的值,如果是则条件为真。 | (A < B) 为真。 |
| >= | 检查左操作数的值是否大于或等于右操作数的值,如果是则条件为真。 | (A >= B) 不为真。 |
| <= | 检查左操作数的值是否小于或等于右操作数的值,如果是则条件为真。 | (A <= B) 为真。 |
逻辑运算符
逻辑运算符对两个表达式执行布尔逻辑运算。C#中的逻辑运算符大体可以分为按位逻辑运算符合布尔逻辑运算符。
1.按位“与”运算符
按位“与”运算符(&)比较两个整数的相应位。
class packing
{
static void Main(string[] args)
{
int num1 = 1; //表明一个int类型的变量num1并初始化为1
int num2 = 85; //表明一个int类型的变量num2并初始化为85
bool iseven; //声明一个bool类型的变量iseven
iseven = (num1 & num2) == 0; //获取两个变量“与”运算后的返回值
Console.WriteLine(iseven); //输出结果
Console.ReadLine();
}
}
程序运行结果为 : False
2.按位“或”运算符
按位“或”运算符(|)用于比较两个整数的相应位。当两个整数的对应位有一个是1或都是1时,返回相应的结果位是1。当两个整数的相应位都是0时,则返回相应的结果位是0。
class packing
{
static void Main(string[] args)
{
int num1 = 1; //表明一个int类型的变量num1并初始化为1
int num2 = 85; //表明一个int类型的变量num2并初始化为85
int iseven; //声明一个bool类型的变量iseven
iseven = (num1 | num2); //获取两个变量“或”运算后的返回值
Console.WriteLine(iseven); //输出结果
Console.ReadLine();
}
}
程序运行结果为 : 85
3.按位“异或”运算符
按位“异或”运算符(^)比较两个整数的相应位。
4.布尔“与”运算符
布尔逻辑运算符对两个布尔表达式执行布尔逻辑计算。 布尔“与”运算符(&)用于计算两个布尔表达式
5.布尔“或”运算符
布尔“或”运算符(|)用于计算两个布尔表达式的结果。当两个布尔表达式中有一个表达式返回真时,则结果为真;当两个布尔表达式的计算结果都是假时, 则结果为假。
6.布尔“异或”运算符
布尔“异或”运算符(^)用于计算两个布尔表达式的结果,只有当其中一个表达式是真而另外一个表达式是假时,该表达式返回的结果才是真;当两个表达式的计算结果都是真或者都是假时,则返回的结果为假。
下表显示了 C# 支持的所有逻辑运算符。假设变量 A 为布尔值 true,变量 B 为布尔值 false,则:
| 运算符 | 描述 | 实例 |
|---|---|---|
| && | 称为逻辑与运算符。如果两个操作数都非零,则条件为真。 | (A && B) 为假。 |
| 双竖杠 | 称为逻辑或运算符。如果两个操作数中有任意一个非零,则条件为真。 | (A 双竖杠B) 为真。 |
| ! | 称为逻辑非运算符。用来逆转操作数的逻辑状态。如果条件为真则逻辑非运算符将使其为假。 | !(A && B) 为真。 |
移位运算符
“<<”和“>>”运算符用于执行移位运算,分别称为左移位运算符和右移位运算符。
1.左移位运算符
使用左移位运算符(<<)可以将数向左移位。其作用是所有的位都向左移动指定的次数,高次位就会丢失,低位以零来填充。
class packing
{
static void Main(string[] args)
{
uint num1 = 4294967295; //表明一个uint类型的变量num1
uint num2; //表明一个uint类型的变量num2
num2=num1<<8; //使num2左移8次
Console.WriteLine(num2); //输出结果
Console.ReadLine();
}
}
程序的运行结果:4294967040
2.右移位运算符
右移位运算符(>>)是把数向右移位。其作用是所有的位都向右移动指定的次数。
class packing
{
static void Main(string[] args)
{
uint num1 = 4294967295; //表明一个uint类型的变量num1
uint num2; //表明一个uint类型的变量num2
num2 = num1 >> 16; //使num2右移16次
Console.WriteLine(num2); //输出结果
Console.ReadLine();
}
}
程序的运行结果:65535
字符型和字符串类型
字符型用 char 关键字表示,存放到 char 类型的字符需要使用单引号括起来,例如 ‘a’、‘中’ 等。
字符串类型能存放多个字符,它是一个引用类型,在字符串类型中存放的字符数可以认为是没有限制的,因为其使用的内存大小不是固定的而是可变的。
使用 string 关键字来存放字符串类型的数据。字符串类型的数据必须使用双引号括起来,例如 “abc”、“123” 等。
字符类Char的使用
Char类概述
Char 在C#中表示一个Unicode字符,正是这些Unicode字符构成了字符串。
转义字符
C#采用字符“\”作为转义字符。例如,定义一个字符,而这个字符是单引号,如果不使用转义字符,则会产生错误。
| 转义字符 | 说明 |
|---|---|
| \n | 回车换行 |
| \t | 横向跳到下一制表位置 |
| \v | 竖向跳格 |
| \b | 退格 |
| \r | 回车 |
| \f | 换页 |
| \ | 反斜线符 |
| ’ | 单引号符 |
| \ddd | 1~3位八进制数所代表的字符 |
| \xhh | 1~2位十六进制数所代表的字符 |
字符串String的使用
创建 String 对象
通过给 String 变量指定一个字符串
通过使用 String 类构造函数
通过使用字符串串联运算符( + )
通过检索属性或调用一个返回字符串的方法
通过格式化方法来转换一个值或对象为它的字符串表示形式
实例
using System;
namespace StringApplication
{
class Program
{
static void Main(string[] args)
{
//字符串,字符串连接
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() ;
}
}
}
当上面的代码被编译和执行时,它会产生下列结果
Full Name: RowanAtkinson
Greetings: Hello
Message: Hello From Tutorials Point
Message: Message sent at 17:58 on Wednesday, 10 October 2012
String 类的属性
String 类有以下两个属性:
| 序号 | 属性名称 & 描述 |
|---|---|
| 1 | Chars 在当前 String 对象中获取 Char 对象的指定位置。 |
| 2 | Length 在当前的 String 对象中获取字符数。 |
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 bool Contains( string value )返回一个表示指定 string 对象是否出现在字符串中的值。 |
| 6 | public static string Copy( string str ) 创建一个与指定字符串具有相同值的新的 String 对象。 |
| 7 | public static bool IsNullOrEmpty( string value ) 指示指定的字符串是否为 null 或者是否为一个空的字符串。 |
| 8 | public bool StartsWith( string value )判断字符串实例的开头是否匹配指定的字符串。 |
| 9 | public string ToUpper() 把字符串转换为大写并返回。 |
比较字符串
在C#中最常见的比较字符串的方法有Compare,CompareTo和Equals等,这些方法都归属于String类。
1.Compare方法
Compare方法用来比较两个字符串是否相等,它有很多个重载方法,其中最常用的两种方法如下:
Int Compare (string strA,string strB)
Int Compare(string strA,string strB,bool ignorCase)
2.CompareTo方法
CompareTo方法与Compare方法相似,都可与比较两个字符串是否相等,不同的是CompareTo方法以实例对象本身与指定的字符串作比较。
3.Equals方法
Equals方法主要用于比较两个字符串是否相同,如果相同返回值是true,否则为false。
示例
static void Main(string[] args)
{
string Str1 = "高冉小可爱"; //声明一个字符串Str1
string Str2 = "高冉小可爱小迷糊"; //声明一个字符串Str2
Console.WriteLine(string.Compare(Str1,Str2)); //输出字符串Str1与Str2比较后的返回值
Console.WriteLine(string.Compare(Str1, Str1)); //输出字符串Str1与Str1比较后的返回值
Console.WriteLine(string.Compare(Str2, Str1)); //输出字符串Str2与Str1比较后的返回值
Console.WriteLine(Str1.CompareTo(Str2)); //输出字符串Str1与Str2比较后的返回值
Console.WriteLine(Str1.Equals(Str2)); //用Equals方法比较字符串Str1和Str2
Console.WriteLine(string .Equals(Str1,Str2)); //用Equals方法比较字符串Str1和Str2
Console.ReadLine();
}
输出结果
-1
0
1
-1
False
False
格式化字符串
使用Format方法格式化两个string类型变量,最后输出格式化后的字符串。
class packing
{
static void Main(string[] args)
{
string Str1 = "高冉小可爱"; //声明一个字符串Str1
string Str2 = "高冉小可爱小迷糊"; //声明一个字符串Str2
string newstr = string.Format("{0},{1}!!!!", Str1, Str2); //格式化字符串
Console.WriteLine(newstr); //输出结果
Console.ReadLine();
}
}
输出结果 :
高冉小可爱,高冉小可爱小迷糊!!!!
用于日期时间的格式规范
| 格式规范 | 说明 |
|---|---|
| d | 简短日期格式(YYYY=MM-dd) |
| D | 完整日期格式(YYYY年MM月dd日) |
| t | 简短时间格式(hh:mm) |
| T | 完整时间格式(hh:mm:ss) |
| f | 简短的日期/时间格式(YYYY年MM月dd日 hh:mm) |
| F | 完整的日期/时间格式(YYYY年MM月dd日 hh:mm:ss) |
| g | 简短的可排序的日期/时间格式(YYYY-MM-dd hh:mmm) |
| G | 完整的可排序的/时间格式(YYYY-MM-dd hh:mm:ss) |
| M或m | 月/日格式(MM月dd日) |
| Y或y | 年/月格式(YYYY年MM月) |
static void Main(string[] args)
{
DateTime dt = DateTime.Now; //获取系统当前日期
string Str1 = string.Format("{0:d}",dt); //格式化成简短日期格式(YYYY-MM-dd)
Console.WriteLine(Str1); //输出结果
string Str2 = string.Format("{0:D}", dt); //格式化成完整日期格式(YYYY年MM月dd日)
Console.WriteLine(Str2); //输出结果
string Str3 = string.Format("{0:t}", dt); //格式化成简短时间格式;(hh:mm)
Console.WriteLine(Str3); //输出结果
string Str4 = string.Format("{0:T}", dt); //完整时间格式; (hh:mmm:ss)
Console.WriteLine(Str4); //输出结果
string Str5 = string.Format("{0:f}", dt); //简短的日期/时间格式; (YYYY年MM月dd日 hh:mm)
Console.WriteLine(Str5); //输出结果
string Str6 = string.Format("{0:F}", dt); //完整的日期/时间格式; (YYYY年MM月dd日 hh:mm:ss)
Console.WriteLine(Str6); //输出结果
string Str7 = string.Format("{0:g}", dt); //简短的可排序的日期/时间格式; (YYYY-MM-dd hh:mm)
Console.WriteLine(Str7); //输出结果
string Str8 = string.Format("{0:G}", dt); //完整的可排序的日期/时间格式; (YYYY-MM-dd hh:mm:ss)
Console.WriteLine(Str8); //输出结果
string Str9 = string.Format("{0:M}", dt); //M或m;月/日格式 (MM月dd日)
Console.WriteLine(Str9); //输出结果
string Str10 = string.Format("{0:Y}", dt); //Y或y; 年/月格式 (YYYY年MM月)
Console.WriteLine(Str10); //输出结果
Console.ReadLine();
}
输出结果
2021/11/14
2021年11月14日
14:49
14:49:58
2021年11月14日 14:49
2021年11月14日 14:49:58
2021/11/14 14:49
2021/11/14 14:49:58
11月14日
2021年11月
截取字符串
String类提供了一个Substring方法,该方法可以截取字符串中指定位置和指定长度的字符。
public string Substring(int startIndex,int length)
startIndex:字符串中的字符数。
Length:字符串中的字符数。
示例:
static void Main(string[] args)
{
string StrA = "用一生下载你"; //声明字符串StrA
string StrB = ""; //声明字符串StrB
StrB = StrA.Substring(1, 4);//截取字符串
Console.WriteLine(StrB); //输出结果
Console.ReadLine();
}
输出结果:
一生下载
分割字符串
String类提供了一个Split方法,用于分割字符串。该方法的返回值是包含所有分割字符串的数组对象,可以通过数组取得所有分割的子字符串。
static void Main(string[] args)
{
string StrA = "用^一生#下载,你"; //声明字符串StrA
char[] separator = { '^', '#', ',' }; //声明分割字符的数组
string[] splitstrings = new string[100]; //声明一个字符串数组
splitstrings = StrA.Split(separator); //分割字符串
for (int i = 0; i < splitstrings.Length; i++)
{
Console.WriteLine("item{0}:{1}",i,splitstrings[i]); //输出结果
}
Console.ReadLine();
}
输出结果
item0: 用
item1:一生
item2:下载
item3:你
插入和填充字符串
1.插入字符串
String类提供了一个Insert方法,用于向字符串的任意位置插入新元素。语法格式如下:
public string Insert(int startIndex,string value);
startIndex:用于指定所要插入的位置,索引从0开始。
value:指定所要插入的字符串。
示例:
static void Main(string[] args)
{
string StrA = "下载"; //声明字符串StrA并赋值“下载”
string strB; //声明字符串变量strB
strB = StrA.Insert(0, "用一生");
string strC = strB.Insert(5, "你");
Console.WriteLine(strC);
Console.ReadLine();
}
输出结果:
用一生下载你
2.填充字符串
String类提供了PadLeft/PadRight方法用于填充字符串,PadLeft方法在字符串的左侧进行字符串的左侧进行字符填充,而PadRight方法在字符串的右侧进行字符填充。
public string PadLeft(int totalWidth,char paddingChar)
totalWidth:指定填充后的字符长度。
paddingChar:指定所要填充的字符,如果省略,则填充空格符合
示例:
class character
{
static void Main(string[] args)
{
string strA = "下载"; //声明字符串StrA并赋值“下载”
string strB = strA.PadLeft(3,'辉'); //声明字符串变量strB,并使用PadLeft方法在StrA的左侧填充字符
string strC = strB.PadRight(4, '好'); //声明字符串StrC,并使用PadRight方法在StrB的右侧填充字符
Console.WriteLine("补充字符串之前:"+strA);
Console.WriteLine("补充字符串之后:" + strC);
Console.ReadLine();
}
}
输出结果:
补充字符串之前:下载
补充字符串之后:辉下载好
删除字符串
String类提供了一个Remove方法,用于从一个字符串的指定位置开始,删除指定数量的字符。
示例:
class character
{
static void Main(string[] args)
{
string strA = "用一生下载你"; //声明字符串StrA并赋值
string strB = strA.Remove(3); //声明字符串变量strB,并使用Remove方法从字符串StrA的索引3开始删除
string strC = strA.Remove(1, 2); //声明字符串StrC,并使用Remove方法在StrA的索引1处开始删除两个字符
Console.WriteLine("索引3开始删除:" + strB);
Console.WriteLine("索引1处开始删除两个字符:" + strC);
Console.ReadLine();
}
}
输出结果:
索引3开始删除:用一生
索引1处开始删除两个字符:用下载你
复制字符串
String类提供了Copy和CopyTo方法,用于将字符串或子字符串复制到另一个字符串或Char类型的数组中。
1.Copy方法
该方法用于创建一个与指定的字符串具有相同值的字符串的新实例。
2.CopyTo方法
CopyTo方法的功能与Copy方法基本相同,但是CopyTo方法可以将字符串的某一部分复制到另一个数组中。
示例:
class character
{
static void Main(string[] args)
{
string strA = "用一生下载你"; //声明字符串StrA并赋值
string strB;//声明字符串变量strB
strB = string.Copy (strA); //使用string类的Copy方法,复制字符串strA的值给strB
char[] str = new char[100]; //声明一个字符数组str
//将字符串str从索引1开始的4个字符串复制到字符数组str中
strA.CopyTo(1,str,0,4);
Console.WriteLine("使用Copy复制strA后数据strB的值:" + strB);
Console.WriteLine(str);
Console.ReadLine();
}
}
输出结果:
使用Copy复制strA后数据strB的值:用一生下载你
一生下载
替换字符串
string类提供了一个Replace方法,用于将字符串中的某个字符或字符串替换成其他的字符或字符串。
class character
{
static void Main(string[] args)
{
string strA = "用一生,下载你"; //声明字符串StrA并赋值
//使用Replace方法将字符串strA中的","替换为"*",并赋值给字符串strB
string strB=strA.Replace(',','*');
Console.WriteLine("使用Replace替换为 * 后数据strB的值:" + strB);
//使用Replace方法将strA中的"用一生"替换为"下一生"
string strC = strA.Replace("用一生", "下一生");
Console.WriteLine("使用Replace替换为下一生后数据strC的值:" + strC);
Console.ReadLine();
}
}
输出结果:
使用Replace替换为 * 后数据strB的值:用一生*下载你
使用Replace替换为下一生后数据strC的值:下一生,下载你
可变字符串类 StringBuilder的使用
StringBuilder类存在于System.Text命名空间中,如果要创建StringBuilder对象,首先必须引用此命名空间。StringBuilder类中的常用方法。
| 方法 | 说明 |
|---|---|
| Append | 将文本或字符串追加到指定对象的末尾 |
| AppendFormat | 自定义变量的格式并将这些值追加到StringBuilder对象的末尾 |
| Insert | 将字符串或对象添加到当前StringBuilder对象中的指定位置 |
| Remove | 从当前StringBuilder对象中移除指定数量的字符 |
| Replace | 用另一个指定的字符来替换StringBuilder对象内的字符 |
static void Main(string[] args)
{
int Num = 1000;
//实例化一个StringBuilder类,并初始化为“用一生下载你”
StringBuilder LS = new StringBuilder("用一生下载你", 100);
LS.Append("VS 小迷糊"); //使用Append方法将字符串追加到LS的末尾
Console.WriteLine(LS);
//使用AppendFormat方法将字符串按照指定的格式追加到LS的末尾
LS.AppendFormat("{0:C}", Num);
Console.WriteLine(LS);
//使用Insert方法将"名称:"追加到LS的开头
LS.Insert(0, "名称:");
Console.WriteLine(LS);
//使用Remove方法从LS中删除索引15以后的字符串
LS.Remove(15, LS.Length - 15);
Console.WriteLine(LS);
//使用Replace方法将"名称:"替换为"一生所爱"
LS.Replace("名称", "一生所爱");
Console.WriteLine(LS);
Console.ReadLine();
}
输出结果:
用一生下载你VS 小迷糊
用一生下载你VS 小迷糊¥1,000.00
名称:用一生下载你VS 小迷糊¥1,000.00
名称:用一生下载你VS 小迷糊
一生所爱:用一生下载你VS 小迷糊
C# 中的注释
注释是用于解释代码。编译器会忽略注释的条目。在 C# 程序中,多行注释以 /* 开始,并以字符 */ 终止,如下所示:
/*if (workorderType != "MANU")
{
MessageBox.Show("此工单不是手工工单,不能删除!");
return;
}*/
单行注释是用 ‘//’ 符号表示。例如:
//controller.SaveHistoryData(workorderId);//先加入历史库
成员变量
变量是类的属性或数据成员,用于存储数据。在上面的程序中,Rectangle(矩形) 类有两个成员变量,名为 length 和 width。
1 using System;
2
3 namespace _12_23
4 {
5 class Program
6 {
7 int lengh = 5;
8 int width = 9;
9 public int Space()
10 {
11 return lengh * width;
12 }
13 public void Print()
14 {
15 Console.WriteLine("长{0}", lengh);
16 Console.WriteLine("宽{0}", width);
17 Console.WriteLine("面积{0}", Space());
18 }
19 static void Main(string[] args)
20 {
21 Program pro = new Program();
22 pro.Space();
23 pro.Print();
24 Console.ReadKey();
25 }
26 }
27 }
成员函数
函数是一系列执行指定任务的语句。类的成员函数是在类内声明的。我们举例的类 Rectangle 包含了三个成员函数: AcceptDetails、GetArea 和 Display。
数据类型
数据类型主要用于指明变量和常量存储值的类型,C# 语言是一种强类型语言,要求每个变量都必须指定数据类型。
C# 语言的数据类型分为值类型和引用类型。
值类型包括整型、浮点型、字符型、布尔型、枚举型等;引用类型包括类、接口、数组、委托、字符串等。
从内存存储空间的角度而言,值类型的值是存放到栈中的,每次存取值都会在该内存中操作;引用类型首先会在栈中创建一个引用变量,然后在堆中创建对象本身,再把这个对象所在内存的首地址赋给引用变量。
整型
C# 语言将整型分成了 byte 类型、short 类型、int 类型、long 类型等 在 C# 语言中默认的整型是 int 类型。
浮点型
浮点型是指小数类型,浮点型在 C# 语言中共有两种,一种称为单精度浮点型,一种称为双精度浮点型。
float 单精度浮点型,占用4个字节,最多保留7位小数
double 双精度浮点型,占用8个字节,最多保留16位小数
C# 判断
| 语句 | 描述 |
|---|---|
| if 语句 | 一个 if 语句 由一个布尔表达式后跟一个或多个语句组成。 |
| if…else 语句 | 一个 if 语句 后可跟一个可选的 else 语句,else 语句在布尔表达式为假时执行。 |
| 嵌套 if 语句 | 您可以在一个 if 或 else if 语句内使用另一个 if 或 else if 语句。 |
| switch 语句 | 一个 switch 语句允许测试一个变量等于多个值时的情况。 |
| 嵌套 switch 语句 | 您可以在一个 switch 语句内使用另一个 switch 语句。 |
C# 循环
| 循环类型 | 描述 |
|---|---|
| while 循环 | 当给定条件为真时,重复语句或语句组。它会在执行循环主体之前测试条件。 |
| if…else 语句 | 一个 if 语句 后可跟一个可选的 else 语句,else 语句在布尔表达式为假时执行。 |
| for/foreach 循环 | 多次执行一个语句序列,简化管理循环变量的代码。 |
| do…while 循环 | 除了它是在循环主体结尾测试条件外,其他与 while 语句类似。 |
| 嵌套循环 | 您可以在 while、for 或 do…while 循环内使用一个或多个循环。 |
C# 封装
封装 被定义为"把一个或多个项目封闭在一个物理的或者逻辑的包中"。在面向对象程序设计方法论中,封装是为了防止对实现细节的访问。
抽象和封装是面向对象程序设计的相关特性。抽象允许相关信息可视化,封装则使开发者实现所需级别的抽象。
一个 访问修饰符 定义了一个类成员的范围和可见性。C# 支持的访问修饰符如下所示:
public:所有对象都可以访问;
private:对象本身在对象内部可以访问;
protected:只有该类对象及其子类对象可以访问
internal:同一个程序集的对象可以访问;
protected internal:访问限于当前程序集或派生自包含类的类型。
C# 方法
一个方法是把一些相关的语句组织在一起,用来执行一个任务的语句块。每一个 C# 程序至少有一个带有 Main 方法的类。
定义方法
调用方法
C# 中定义方法
当定义一个方法时,从根本上说是在声明它的结构的元素。在 C# 中,定义方法的语法如下:
<Access Specifier> <Return Type> <Method Name>(Parameter List)
{
Method Body
}
下面是方法的各个元素:
Access Specifier:访问修饰符,这个决定了变量或方法对于另一个类的可见性。
Return type:返回类型,一个方法可以返回一个值。返回类型是方法返回的值的数据类型。如果方法不返回任何值,则返回类型为 void。
Method name:方法名称,是一个唯一的标识符,且是大小写敏感的。它不能与类中声明的其他标识符相同。
Parameter list:参数列表,使用圆括号括起来,该参数是用来传递和接收方法的数据。参数列表是指方法的参数类型、顺序和数量。参数是可选的,也就是说,一个方法可能不包含参数。
Method body:方法主体,包含了完成任务所需的指令集。
C# 可空类型(Nullable)
? 单问号用于对 int、double、bool 等无法直接赋值为 null 的数据类型进行 null 的赋值,意思是这个数据类型是 Nullable 类型的。
?? 双问号用于判断一个变量在为 null 的时候返回一个指定的值。
C# 字符串(String)
在 C# 中,您可以使用字符数组来表示字符串,但是,更常见的做法是使用 string 关键字来声明一个字符串变量。string 关键字是 System.String 类的别名。
C# 结构体(Struct)
在 C# 中,结构体是值类型数据结构。它使得一个单一变量可以存储各种数据类型的相关数据。struct 关键字用于创建结构体。
定义结构体
struct Books
{
public string title;
public string author;
public string subject;
public int book_id;
};
C# 结构的特点
在 C# 中的结构与传统的 C 或 C++ 中的结构不同。C# 中的结构有以下特点:
结构可带有方法、字段、索引、属性、运算符方法和事件。
结构可定义构造函数,但不能定义析构函数。但是,您不能为结构定义无参构造函数。无参构造函数(默认)是自动定义的,且不能被改变。
与类不同,结构不能继承其他的结构或类。
结构不能作为其他结构或类的基础结构。
结构可实现一个或多个接口。
结构成员不能指定为 abstract、virtual 或 protected。
当您使用 New 操作符创建一个结构对象时,会调用适当的构造函数来创建结构。与类不同,结构可以不使用 New 操作符即可被实例化。
如果不使用 New 操作符,只有在所有的字段都被初始化之后,字段才被赋值,对象才被使用。
C# 接口(Interface)
接口定义了所有类继承接口时应遵循的语法合同。接口定义了语法合同 “是什么” 部分,派生类定义了语法合同 “怎么做” 部分。
接口定义了属性、方法和事件,这些都是接口的成员。接口只包含了成员的声明。成员的定义是派生类的责任。接口提供了派生类应遵循的标准结构。
接口使得实现接口的类或结构在形式上保持一致。
抽象类在某种程度上与接口类似,但是,它们大多只是用在当只有少数方法由基类声明由派生类实现时。
接口本身并不实现任何功能,它只是和声明实现该接口的对象订立一个必须实现哪些行为的契约。
抽象类不能直接实例化,但允许派生出具体的,具有实际功能的类。
定义接口: MyInterface.cs
接口使用 interface 关键字声明,它与类的声明类似。接口声明默认是 public 的。下面是一个接口声明的实例:
interface IMyInterface
{
void MethodToImplement();
}
以上代码定义了接口 IMyInterface。通常接口命令以 I 字母开头,这个接口只有一个方法 MethodToImplement(),没有参数和返回值,当然我们可以按照需求设置参数和返回值。
值得注意的是,该方法并没有具体的实现。
接下来我们来实现以上接口:InterfaceImplementer.cs
using System;
interface IMyInterface
{
// 接口成员
void MethodToImplement();
}
class InterfaceImplementer : IMyInterface
{
static void Main()
{
InterfaceImplementer iImp = new InterfaceImplementer();
iImp.MethodToImplement();
}
public void MethodToImplement()
{
Console.WriteLine("MethodToImplement() called.");
}
}
InterfaceImplementer 类实现了 IMyInterface 接口,接口的实现与类的继承语法格式类似:
class InterfaceImplementer : IMyInterface
继承接口后,我们需要实现接口的方法 MethodToImplement() , 方法名必须与接口定义的方法名一致。
接口继承: InterfaceInheritance.cs
以下实例定义了两个接口 IMyInterface 和 IParentInterface。
如果一个接口继承其他接口,那么实现类或结构就需要实现所有接口的成员。
以下实例 IMyInterface 继承了 IParentInterface 接口,因此接口实现类必须实现 MethodToImplement() 和 ParentInterfaceMethod() 方法:
using System;
interface IParentInterface
{
void ParentInterfaceMethod();
}
interface IMyInterface : IParentInterface
{
void MethodToImplement();
}
class InterfaceImplementer : IMyInterface
{
static void Main()
{
InterfaceImplementer iImp = new InterfaceImplementer();
iImp.MethodToImplement();
iImp.ParentInterfaceMethod();
}
public void MethodToImplement()
{
Console.WriteLine("MethodToImplement() called.");
}
public void ParentInterfaceMethod()
{
Console.WriteLine("ParentInterfaceMethod() called.");
}
}
实例输出结果为:
MethodToImplement() called.
ParentInterfaceMethod() called.
C# 预处理器指令
预处理器指令指导编译器在实际编译开始之前对信息进行预处理。
所有的预处理器指令都是以 # 开始。且在一行上,只有空白字符可以出现在预处理器指令之前。预处理器指令不是语句,所以它们不以分号(;)结束。
C# 编译器没有一个单独的预处理器,但是,指令被处理时就像是有一个单独的预处理器一样。在 C# 中,预处理器指令用于在条件编译中起作用。与 C 和 C++ 不同的是,它们不是用来创建宏。一个预处理器指令必须是该行上的唯一指令。
C# 预处理器指令列表
下表列出了 C# 中可用的预处理器指令:
| 预处理器指令 | 描述 |
|---|---|
| #define | 它用于定义一系列成为符号的字符。 |
| #undef | 它用于取消定义符号。 |
| #if | 它用于测试符号是否为真 |
| #else | 它用于创建复合条件指令,与 #if 一起使用。 |
| #elif | 它用于创建复合条件指令。 |
| #endif | 指定一个条件指令的结束。 |
| #line | 它可以让您修改编译器的行数以及(可选地)输出错误和警告的文件名。 |
| #error | 它允许从代码的指定位置生成一个错误。 |
| #warning | 它允许从代码的指定位置生成一级警告。 |
| #region | 它可以让您在使用 Visual Studio Code Editor 的大纲特性时,指定一个可展开或折叠的代码块。 |
| #endregion | 它标识着 #region 块的结束。 |
条件指令
常见运算符有:
== (等于)
!= (不等于)
&& (与)
|| (或)
C# 正则表达式
正则表达式 是一种匹配输入文本的模式。
.Net 框架提供了允许这种匹配的正则表达式引擎。
模式由一个或多个字符、运算符和结构组成。
定义正则表达式
下面列出了用于定义正则表达式的各种类别的字符、运算符和结构。
字符转义
字符类
定位点
分组构造
限定符
反向引用构造
备用构造
替换
杂项构造
字符转义
正则表达式中的反斜杠字符(\)指示其后跟的字符是特殊字符,或应按原义解释该字符。
C# 异常处理
异常是在程序执行期间出现的问题。C# 中的异常是对程序运行时出现的特殊情况的一种响应,比如尝试除以零。
异常提供了一种把程序控制权从某个部分转移到另一个部分的方式。C# 异常处理时建立在四个关键词之上的:try、catch、finally 和 throw。
try:一个 try 块标识了一个将被激活的特定的异常的代码块。后跟一个或多个 catch 块。
catch:程序通过异常处理程序捕获异常。catch 关键字表示异常的捕获。
finally:finally 块用于执行给定的语句,不管异常是否被抛出都会执行。例如,如果您打开一个文件,不管是否出现异常文件都要被关闭。
throw:当问题出现时,程序抛出一个异常。使用 throw 关键字来完成。
语法
假设一个块将出现异常,一个方法使用 try 和 catch 关键字捕获异常。try/catch 块内的代码为受保护的代码,使用 try/catch 语法如下所示:
try
{
// 引起异常的语句
}
catch( ExceptionName e1 )
{
// 错误处理代码
}
catch( ExceptionName e2 )
{
// 错误处理代码
}
catch( ExceptionName eN )
{
// 错误处理代码
}
finally
{
// 要执行的语句
}
您可以列出多个 catch 语句捕获不同类型的异常,以防 try 块在不同的情况下生成多个异常。
—标识符
1.不能以数字开头
2.@符号只能放在前面–为了转义关键字