一、 字符串
1. 日期格式化
| 说明符 | 名称 | 示例输出 (zh-CN) | 描述 |
|---|---|---|---|
t | 短时间 | 17:58 | 小时:分钟 |
D | 长日期 | 2012年10月10日 | 完整年月日 |
f | 完整日期时间 | 2012年10月10日 17:58 | 长日期 + 短时间 |
g | 常规日期时间 | 2012/10/10 17:58 | 短日期 + 短时间 |
二、 结构体
1. 值类型 vs 引用类型:
- 结构是值类型(Value Type): 结构是值类型,它们在栈上分配内存,而不是在堆上。当将结构实例传递给方法或赋值给另一个变量时,将复制整个结构的内容。
- 类是引用类型(Reference Type): 类是引用类型,它们在堆上分配内存。当将类实例传递给方法或赋值给另一个变量时,实际上是传递引用(内存地址)而不是整个对象的副本。
三、 枚举
1. 声明 enum 变量
enum <enum_name>
{
enumeration list
};
四、 类
1. 修饰符
| 访问修饰符 | 含义 | 谁能访问? | 比喻 |
|---|---|---|---|
public | 公共的,无限制 | 任何代码(无论内外项目) | 公司大厅 |
internal | 内部的,程序集私有(默认) | 仅限同一个项目内的代码 | 内部部门 |
private | 私有的 | 仅限声明它的那个类自身 | 个人笔记 |
protected | 受保护的 | 类自身和它的所有派生类(子类) | 家族遗传 |
五、 继承
C# 不支持类的多重继承,但支持接口的多重继承,一个类可以实现多个接口
1. 基本语法
<访问修饰符> class <基类>
{
...
}
class <派生类> : <基类>
{
...
}
六、 多态性
1. 静态多态性
- 函数重载
- 运算符重载
2. 动态多态性
2.1. 关键字
| 关键字 | 使用位置 | 是否有方法体? | 子类行为 | 目的 |
|---|---|---|---|---|
abstract | 抽象类的方法 | 否 (只有声明) | 必须 override (强制实现) | 定义一个必须由子类完成的契约,但无默认实现 |
virtual | 基类的方法 | 是 (提供默认实现) | 可以选择性地 override (可选重写) | 提供一个可被子类定制的默认行为 |
override | 派生类的方法 | 是 (提供新实现) | - (本身就是重写行为) | 为基类的 abstract 或 virtual 方法提供新实现 |
七、 运算符重载
1. 示例
public static Box operator+ (Box b, Box c)
{
Box box = new Box();
box.length = b.length + c.length;
box.breadth = b.breadth + c.breadth;
box.height = b.height + c.height;
return box;
}
八、 接口
接口默认共有,类中方法默认私有
1. 定义接口
接口使用 interface 关键字声明,它与类的声明类似。接口声明默认是 public 的。
/// <summary>
/// 定义了日志记录器的行为规范。
/// 任何实现了此接口的类都能够记录不同级别的消息。
/// </summary>
public interface ILogger
{
/// <summary>
/// 记录一条普通信息。
/// </summary>
/// <param name="message">要记录的消息文本。</param>
void LogInfo(string message);
/// <summary>
/// 记录一条警告信息。
/// </summary>
/// <param name="message">要记录的警告文本。</param>
void LogWarning(string message);
/// <summary>
/// 记录一条错误信息。
/// </summary>
/// <param name="message">要记录的错误文本。</param>
/// <param name="exception">可选的异常对象。</param>
void LogError(string message, Exception? ex = null); // C# 8.0+ 支持可空引用类型
}
一个接口中的属性声明,规定了实现类必须提供对应的 get 和或 set 访问器。
九、 预处理指令
1. 条件编译
1.1. #define 和 #undef:定义或取消定义符号
1.2. #if, #elif, #else, #endif:条件代码块
2. 错误和警告报告
2.1. #error:生成编译错误
2.2. #warning:生成编译警告
十、 异常处理
1. 四个关键字
- try:一个 try 块标识了一个将被激活的特定的异常的代码块。后跟一个或多个 catch 块。
- catch:程序通过异常处理程序捕获异常。catch 关键字表示异常的捕获。
- finally:finally 块用于执行给定的语句,不管异常是否被抛出都会执行。例如,如果您打开一个文件,不管是否出现异常文件都要被关闭。
- throw:当问题出现时,程序抛出一个异常。使用 throw 关键字来完成。
十一、 文件的输入和输出
十二、 特性
1. 规定特性
[attribute(positional_parameters, name_parameter = value, ...)]
element
2. 预定义特性
2.1. Obsolete 特性:标记过时成员
产生一个默认警告:
[Obsolete]
public void OldMethod() { /* ... */ }
产生一个带自定义消息的警告
[Obsolete("This method is outdated. Please use NewMethod() instead.")]
public void OldMethod() { /* ... */ }
产生一个编译错误,强制停止使用
[Obsolete("This method has been completely removed. You must use NewMethod().", true)] // 第二个参数为 true
public void VeryOldMethod() { /* ... */ }
2.2. Conditional 特性:条件编译方法
重要规则:
- 被
[Conditional]修饰的方法返回值必须是void。 - 它不能是接口方法的实现。
2.3. AttributeUsage 特性:定义你自己的特性如何被使用
规定自己特性的类必须继承System.Attribute
在 C# 中,特性类的名称通常以后缀 Attribute 结尾(例如 AuthorAttribute)。当你在代码中使用这个特性时,可以省略掉 Attribute 这个后缀。
规定语法如下:
[AttributeUsage(
validon,
AllowMultiple=allowmultiple,
Inherited=inherited
)]
- 参数 validon 规定特性可被放置的语言元素。它是枚举器 AttributeTargets 的值的组合。默认值是 AttributeTargets.All。
- 参数 allowmultiple(可选的)为该特性的 AllowMultiple 属性(property)提供一个布尔值。如果为 true,则该特性是多用的。默认值是 false(单用的)。
- 参数 inherited(可选的)为该特性的 Inherited 属性(property)提供一个布尔值。如果为 true,则该特性可被派生类继承。默认值是 false(不被继承)。
例如:
[AttributeUsage(AttributeTargets.Class |
AttributeTargets.Constructor |
AttributeTargets.Field |
AttributeTargets.Method |
AttributeTargets.Property,
AllowMultiple = true)]
2.4. Serializable:标记类可以被序列化
序列化是将对象转换为可以存储或传输的形式的过程
2.5. DllImport:用于导入非托管代码中的方法
十三、 反射
1. 查看元数据
System.Reflection 类的 MemberInfo 对象需要被初始化,用于发现与类相关的特性(attribute)。
System.Reflection.MemberInfo info = typeof(MyClass);
GetCustomAttributes 方法返回的特性数组的顺序是未定义的 (undefined) 。
十四、 属性
类中重写 Tostring 方法时, 任何需要将该类实例转换为字符串来显示的地方,都会自动调用你写的这个版本。
十五、 索引器
基本语法
element-type this[int index]
{
// get 访问器
get
{
// 返回 index 指定的值
}
// set 访问器
set
{
// 设置 index 指定的值
}
}
十六、 委托
委托不持有数据,它持有的是对一个 “操作”或“行为”(也就是方法)的引用。
“委托的方法需要有跟委托一样的返回类型和参数”
在 C# 中,委托(Delegate) 是一种类型安全的函数指针,它允许将方法作为参数传递给其他方法。
C# 中的委托(Delegate)类似于 C 或 C++ 中函数的指针。委托(Delegate) 是存有对某个方法的引用的一种引用类型变量,引用可在运行时被改变。
声明委托的语法
public delegate <return type> <delegate-name> <parameter list>
中文格式
public delegate 返回类型 委托名(参数类型 参数名, ...);
十七、 事件
事件(Event) 基本上说是一个用户操作,如按键、点击、鼠标移动等等,或者是一些提示信息,如系统生成的通知。应用程序需要在事件发生时响应事件。例如,中断。
C# 中使用事件机制实现线程间的通信。
关键点:
- 声明委托:定义事件将使用的委托类型。委托是一个函数签名。
- 声明事件:使用
event关键字声明一个事件。 - 触发事件:在适当的时候调用事件,通知所有订阅者。
- 订阅和取消订阅事件:其他类可以通过
+=和-=运算符订阅和取消订阅事件。
1. 声明事件
声明该事件的委托类型
public delegate void BoilerLogHandler(string status);
声明事件本身
// 基于上面的委托定义事件
public event BoilerLogHandler BoilerEventLog;
十八、 多线程
1. 创建线程
ThreadStart childref = new ThreadStart(CallToChildThread);
Console.WriteLine("In Main: Creating the Child thread");
Thread childThread = new Thread(childref);
childThread.Start();
2. 销毁线程
Abort() 方法用于销毁线程。
十九、 泛型
public T Add<T>(T a, T b)
{
// 将 a 和 b 转换为 dynamic 类型
// 运行时,DLR (动态语言运行时) 会检查 a 和 b 的真实类型
// 如果它们确实支持 + 运算符,就执行,否则抛出异常。
dynamic dynA = a;
dynamic dynB = b;
return dynA + dynB;
}
// 用法:
int resultInt = Add(5, 10); // 正常工作
double resultDouble = Add(3.5, 2.1); // 正常工作
string resultString = Add("Hello ", "World"); // 正常工作
// Person p1 = new Person(), p2 = new Person();
// Add(p1, p2); // 运行时会抛出异常,因为 Person 类没有定义 + 运算符
二十、 匿名方法
1. lambda 表达式
语法:
(parameters) => expression
// 或
(parameters) => { statement; }
示例: Func sum = (int x, int y) => x + y;
2. 匿名方法
通过使用 delegate 关键字创建委托实例来声明的。
语法:delegate(parameters) { statement; }
二十一、 不安全代码
当一个代码块使用 unsafe 修饰符标记时,C# 允许在函数中使用指针变量。不安全代码或非托管代码是指使用了指针变量的代码块。
1. 编译不安全代码
在命令行中输入csc /unsafe prog1.cs
二十二、 var 和 dynamic 关键字
1. var 隐式类型局部变量
1.1. 规则
- 必须在声明时初始化
- 不能用null初始化
- 只能用于局部变量
1.2. 什么时候用
- 使用 new 关键字创建实例时
二十三、 特性 Attribute
1. 使用场景
- 数据注解特性
- [Requrired] 用于标记数据字段为必填项
- [Stringlength] 用于限制字符串的最大长度
- [Range] 用于指定数值的范围
- [EmailAddress] 用于验证电子邮箱地址的格式
- 验证机制
- 使用 Validator 类可以对数据模型进行验证。如果模型不符合验证规则,Validator 将抛出异常
2. 日志记录与审查
- 自定义日志记录特性
- 使用AOP框架实现日志记录
3. 特性运行时的处理
- 使用反射获取特性
- 特性和依赖注入
4. 高级应用
- 特性与代码生成
- 特性与元数据扩展

Comments NOTHING