示例:Enum类型的转换
enum Weekday
{
Monday,
Tuesday,
Wednesday,
Thursday,
Friday
}
string input = "Monday";
Weekday weekday;
Enum.TryParse(input, out weekday);
return语句只能从函数返回一个值,可以使用输出参数(out标记的)从函数中返回多个值。
示例:
private static void TestFunc(out int x, out int y)
{
x = 0;
y = 1;
}
int i;
int j;
TestFunc(out i, out j);
总的来说:结构比类轻量级
(1)类适合表示复杂的对象和行为,支持继承和多态等,
而结构更适合表示轻量级的数据和值
这样可以提高性能并避免引用的管理开销
(2)结构是值类型,结构实例赋值时是将整个结构进行复制
类是引用类型,类实例赋值时时传递引用(内存地址)
性能: 快(栈的指针移动分配内存) / 慢(内存管理算法)
物理内存: 连续内存块,通常MB级别 / 非连续,系统物理内存上限
分配方式:自动 / new
生命周期:随作用域结束自动释放 / 需要显示释放或者GC
数据类型:局部变量、值类型、结构体 / 类、数组
编译器在编译之前对信息进行预处理。
(1)通过#region可以帮助分隔代码块
(2)通过#if指令可以在开发和生产环境中编译不同的代码(DEBUG为特殊预定义符号,不需要#define定义)
示例1:
#if DEBUG
Console.WriteLine("Debug");
#else
Console.WriteLine("Release");
#endif
示例2:
#define PI
#if PI
Console.WriteLine("3.14");
#else
Console.WriteLine("4");
#endif
(3)#pragma用于向编译器发送特殊指定
示例:
#pragma warning disable 414
private int unusedVariable;
#pragma warning restore 414
通过属性(首字母通常大写)控制字段的访问和设置
示例:
class Person
{
private int name;
public int Name { get { return name; } set { name = value; } }
}
Person p = new Person();
p.Name = 10;
Console.WriteLine(p.Name);
定义:一种类型安全的函数指针。
声明方式:public delegate 返回类型 委托名(参数类型 参数名, ...); // 就是在返回类型之前增加了delegate关键字
示例1:基本用法
delegate int NumberChanger(int n);
internal class Program
{
static int num = 10;
public static int addNum(int p)
{
num += p;
return num;
}
public static int multNum(int p)
{
num *= p;
return num;
}
public static int getNum()
{
return num;
}
static void Main(string[] args) {
NumberChanger p1 = new NumberChanger(addNum);
NumberChanger p2 = new NumberChanger(multNum);
p1(10);
Console.WriteLine(num); // 返回20
p2(2);
Console.WriteLine(num); // 返回40
}
}
定义:委托对象使用+运算符合并相同类型的委托。
作用:创建一个委托要调用方法的列表,然后依次执行。
示例2:
只修改上述方法的Main函数:
NumberChanger p;
NumberChanger p1 = new NumberChanger(addNum);
NumberChanger p2 = new NumberChanger(multNum);
p = p1;
p += p2;
p(2); // 返回24
Console.WriteLine(getNum());
委托机制允许委托类型方法的参数作为参数传递给其他方法。
示例3:参数传递
在示例1中增加如下方法:
public static void printChange(NumberChanger p)
{
Console.WriteLine(p(3));
}
Main函数修改如下:
NumberChanger p;
NumberChanger p1 = new NumberChanger(addNum);
NumberChanger p2 = new NumberChanger(multNum);
p = p1;
p += p2;
p(2); // 返回24
Console.WriteLine(getNum());
printChange(p1); // 返回27
printChange(p2); // 返回81
Console.ReadLine();
更简单的委托定义方式,代表不返回值的方法。接受0-16个参数的委托。
无参数的示例:
public static void printMessage() {
Console.WriteLine("hello");
}
static void Main(string[] args) {
Action action = printMessage;
action();
}
有参数的示例:
public static void printMessage(string message, int age) {
Console.WriteLine(message + age);
}
static void Main(string[] args) {
Action action = printMessage;
action("hello", 30);
}
定义:封装了委托的类型,它允许我们更方便地在不同的类之间“发送提醒”
实现步骤:
1)声明委托:定义事件将使用的委托类型,如果使用Action则不需要此步
2)声明事件:使用event关键字声明一个事件
3)触发事件:在适当的时候调用事件,通知所有订阅者
4)订阅和取消订阅事件:其他类通过+=和-=订阅和取消订阅事件
示例:
class EventHandler
{
public static event Action sayHelloEvent;
public static void callHelloEvent()
{
if(sayHelloEvent != null)
{
sayHelloEvent();
}
}
}
internal class Program
{
public static void printMessage()
{
Console.WriteLine("hello Program");
}
static void Main(string[] args) {
EventHandler.sayHelloEvent += printMessage;
EventHandler.callHelloEvent();
Console.ReadLine();
}
}
协程:一种特殊函数,允许暂停执行并在某个时间点恢复,而不会阻塞主线程。协程由IEnumerator接口和yield return语句实现,通常用于实现需分布执行的任务。
线程:系统级别的多任务实现,允许程序同时执行多个独立的代码块。
区别:协程在主线程中执行,是应用程序级别的并发。