Unity开发之C#高阶知识

1、类型转换TryParse

示例:Enum类型的转换

enum Weekday
{
    Monday,
    Tuesday, 
    Wednesday,
    Thursday,
    Friday
}

string input = "Monday";
Weekday weekday;
Enum.TryParse(input, out weekday);

2、按输出传递参数


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);

3、类 VS 结构


总的来说:结构比类轻量级
(1)类适合表示复杂的对象和行为,支持继承和多态等,
而结构更适合表示轻量级的数据和值
这样可以提高性能并避免引用的管理开销
(2)结构是值类型,结构实例赋值时是将整个结构进行复制
类是引用类型,类实例赋值时时传递引用(内存地址)

4、栈内存 VS 堆内存


性能: 快(栈的指针移动分配内存) / 慢(内存管理算法)
物理内存: 连续内存块,通常MB级别 / 非连续,系统物理内存上限
分配方式:自动  / new
生命周期:随作用域结束自动释放 / 需要显示释放或者GC
数据类型:局部变量、值类型、结构体 / 类、数组

5、预处理指令


编译器在编译之前对信息进行预处理。
(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

6、属性


通过属性(首字母通常大写)控制字段的访问和设置
示例:

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);

7、委托


(1)基本定义


定义:一种类型安全的函数指针。
声明方式: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)多播


定义:委托对象使用+运算符合并相同类型的委托。
作用:创建一个委托要调用方法的列表,然后依次执行。
示例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)作为参数传递


委托机制允许委托类型方法的参数作为参数传递给其他方法。
示例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();

(4)Action委托


更简单的委托定义方式,代表不返回值的方法。接受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);
}

8、事件


定义:封装了委托的类型,它允许我们更方便地在不同的类之间“发送提醒”
实现步骤:
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();
    }
}

9、协程和线程的定义和区别


协程:一种特殊函数,允许暂停执行并在某个时间点恢复,而不会阻塞主线程。协程由IEnumerator接口和yield return语句实现,通常用于实现需分布执行的任务。
线程:系统级别的多任务实现,允许程序同时执行多个独立的代码块。

区别:协程在主线程中执行,是应用程序级别的并发。

你可能感兴趣的:(Unity开发之C#高阶知识)