unity游戏开发-6-unity 基础:数据类型、条件、循环、函数、委托、泛型

1. 数据类型

1.1 整型

  • 创建变量的语法
<类型> <变量名> = <值>;
  • int
    • 举例:
int age = 25;
  • long
    • 举例:
long bigNumber = 1234567890123456789;
  • short
    • 举例:
short smallNumber = 123;
  • char
    • 举例:
char letter = 'A';
  • byte(8位无符号整数)
    • 举例:
byte singleByte = 255;
  • bool
    • 举例:
bool isAlive = true;

1.2 枚举

  • 语法
    • 定义
public enum <枚举类型> 
{
    <枚举值1>,
    <枚举值2>,
    ...
}
  • 创建枚举变量
<枚举类型> <变量名> = <枚举类型>.<枚举值>;
  • 举例
public enum DayOfWeek
{
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday,
    Sunday
}

DayOfWeek today = DayOfWeek.Monday;

1.3 浮点

  • float
    • 举例:
float price = 19.99f;
  • double
    • 举例:
double highPrecision = 3.141592653589793;

1.4 可遍历的类型

1.4.1 数组

  • 举例
int[] numbers = new int[5] { 1, 2, 3, 4, 5 };

1.4.2 列表

  • 举例
using System.Collections.Generic;

List<string> names = new List<string>();
names.Add("Alice");
names.Add("Bob");

List<float> fList = new() { 3.1F, 3.2F };

1.4.3 字典

  • 举例
using System.Collections.Generic;

List<string> names = new List<string>();
names.Add("Alice");
names.Add("Bob");

Dictionary<string, int> siDic = new() 
{ 
    ["abcd"] = 4, 
    ["efg"] = 3 
};

1.5 结构、类

1.5.1 结构

  • 举例
struct Point
{
    public int X;
    public int Y;

    public Point(int x, int y)
    {
        X = x;
        Y = y;
    }
}

// 不使用 new,直接赋值
Point p1;
p1.X = 10;
p1.Y = 20;

// 使用 new 调用构造函数
Point p2 = new Point(30, 40);

// 或者直接初始化
Point p3 = new Point { X = 50, Y = 60 };

1.5.2 类

  • 举例
class MyClass
{
    public int Value;

    public MyClass(int value)
    {
        Value = value;
    }
}

// 使用 new 创建类的实例
MyClass obj = new MyClass(10);

1.5.3 对比

  • class:

    • 属于引用类型,存储在堆内存中。
    • 支持继承,可以定义析构函数。
    • 适合存储较大的对象或需要频繁共享的对象。
  • struct:

    • 属于值类型,一般存储在栈内存中(虽然 struct 是值类型,但在某些情况下,如存储在引用类型中或装箱时,它仍然会被分配在堆内存中)。
      • 局部变量:通常分配在 栈内存 中。
      • 作为引用类型的一部分:分配在 堆内存 中。
      • 作为类的字段:分配在 堆内存 中。
      • 装箱:分配在 堆内存 中。
    • 不支持继承,不能定义析构函数。
    • 适合存储较小的对象或频繁创建和销毁的对象。
  • 构造函数用于初始化对象,析构函数(仅适用于 class)用于清理资源,但通常可以通过实现 IDisposable 接口来更安全地管理资源。

1.6 关于 new 的使用

1.6.1 什么情况下使用 new

  • 数组:必须使用 new 来分配内存。
  • 结构体(struct):可以使用 new 来调用构造函数,但也可以直接赋值。
  • 类(class):必须使用 new 来创建实例。
  • 值类型(如 int, float 等):不需要使用 new,直接赋值即可。
  • 字符串(string):可以使用 new 或直接赋值。

1.6.2 关于 new 的语法

  • 调用 类、结构 的构造函数时,使用 ()
  • 也可以使用 对象初始化器 {}

1.7 隐式类型推断

在某些情况下,C# 允许省略显式类型声明,使用 var 关键字进行隐式类型推断。编译器会根据赋值表达式推断出变量的类型。

class MyClass
{
    public int Value;
    public string Name;
}

struct MyStruct
{
    public int X;
    public int Y;
}

void Method()
{
    // 使用 var 进行隐式类型推断
    var obj = new MyClass(10); // 编译器推断 obj 的类型为 MyClass
    var s = new MyStruct(1, 2); // 编译器推断 s 的类型为 MyStruct

    // 使用 var 和对象初始化器
    var obj2 = new MyClass { Value = 20, Name = "Moonshot" };

    // 使用 var 和匿名类型
    var anon = new { Value = 30, Name = "Anonymous" }; // 匿名类型
}

2. 条件语句

2.1 if - else if - else

if (condition1)
{
    // 条件1为 true 时执行的代码
}
else if (condition2)
{
    // 条件2为 true 时执行的代码
}
else
{
    // 所有条件都不满足时执行的代码
}

2.2 switch

2.2.1 基础语法

switch (expression)
{
    case value1:
        // 表达式等于 value1 时执行的代码
        break;
    case value2:
        // 表达式等于 value2 时执行的代码
        break;
    default:
        // 默认情况下执行的代码
        break;
}

2.2.2 when (C# 7.0+)

  • switch 语句支持 when 关键字,用于在 case 中添加额外的条件。
int dayOfWeek = 3;
switch (dayOfWeek)
{
    case 1 when (dayOfWeek > 0):
        Console.WriteLine("Monday");
        break;
    case 2 when (dayOfWeek > 0):
        Console.WriteLine("Tuesday");
        break;
    case 3 when (dayOfWeek > 0):
        Console.WriteLine("Wednesday");
        break;
    default:
        Console.WriteLine("Invalid day");
        break;
}

2.2.3 swich 表达式(C# 8.0+)

int dayOfWeek = 3;
string dayName = dayOfWeek switch
{
    1 => "Monday",
    2 => "Tuesday",
    3 => "Wednesday",
    4 => "Thursday",
    5 => "Friday",
    6 => "Saturday",
    7 => "Sunday",
    _ => "Invalid day"
};
Console.WriteLine(dayName);

2.3 三元运算符 (xx ? xx : xx)

condition ? value1 : value2;

2.4 合并 空赋值 运算(??=)(C# 8.0+)

  • 判断值是否为空,为空则赋值
  • 举例1
string myString = null;

// 如果 myString 为 null,则赋值为 "default"
myString ??= "default";

Console.WriteLine(myString); // 输出:default
  • 举例2
funcItemToStr ??= item => $"{item}";
  • 解析
    • funcItemToStr:
      这是一个变量,类型为委托(例如:ItemToStr<T>),它可能为 null。

    • ??=:
      这是空合并赋值运算符。它的作用是:
      如果 funcItemToStr 当前为 null,则将其赋值为右侧的表达式。
      如果 funcItemToStr 不为 null,则不进行任何操作。

    • item => $“{item}”:
      这是一个 Lambda 表达式,表示一个委托,接受一个参数 item,并返回其字符串表示形式。

3. 循环

在 C# 中,循环语句用于重复执行一段代码,直到满足某个条件为止。C# 提供了多种循环语句,包括 forwhiledo-whileforeach。以下是对这些循环语句的详细说明和示例:

3.1 for 循环

for 循环是最常用的循环语句,适用于已知循环次数的情况。

  • 语法:
for (初始化; 条件; 迭代器)
{
    // 循环体
}
  • 示例:
for (int i = 0; i < 5; i++)
{
    Console.WriteLine(i); // 输出 0 到 4
}

3.2 while 循环

while 循环用于在条件为 true 时重复执行代码块。如果条件为 false,则不执行循环体。

  • 语法:
while (条件)
{
    // 循环体
}
  • 示例:
int i = 0;
while (i < 5)
{
    Console.WriteLine(i); // 输出 0 到 4
    i++;
}

3.3 do-while 循环

do-while 循环与 while 循环类似,但 do-while 循环会至少执行一次循环体,即使条件为 false

  • 语法:
do
{
    // 循环体
} while (条件);
  • 示例:
int i = 0;
do
{
    Console.WriteLine(i); // 输出 0 到 4
    i++;
} while (i < 5);

3.4 foreach 循环

foreach 循环用于遍历集合(如数组、列表等)中的每个元素。它不需要显式地管理索引。

  • 语法:
foreach (类型 变量 in 集合)
{
    // 循环体
}
  • 示例:
int[] numbers = { 1, 2, 3, 4, 5 };
foreach (int number in numbers)
{
    Console.WriteLine(number); // 输出 1 到 5
}

3.5 breakcontinue

  • break:用于退出当前循环。

  • continue:用于跳过当前循环的剩余部分,直接进入下一次迭代。

  • 示例:

for (int i = 0; i < 10; i++)
{
    if (i == 5)
    {
        break; // 退出循环
    }
    Console.WriteLine(i); // 输出 0 到 4
}

for (int i = 0; i < 10; i++)
{
    if (i % 2 == 0)
    {
        continue; // 跳过偶数
    }
    Console.WriteLine(i); // 输出 1, 3, 5, 7, 9
}

3.6 goto 语句

虽然不推荐使用,但 goto 语句可以用于跳转到指定的标签。它在某些特殊场景下(如状态机)可能有用。

  • 示例:
int i = 0;
start:
if (i < 5)
{
    Console.WriteLine(i); // 输出 0 到 4
    i++;
    goto start;
}

4. 函数、委托、泛型

4.1 函数

4.1.1 全局方法(C# 9.0+)

  • 全局方法的位置
    全局方法必须定义在文件的顶层,不能嵌套在类或结构体中。它们通常位于文件的开头部分。

  • 全局方法的作用域
    全局方法的作用域是整个文件,但它们只能在定义它们的文件中使用。全局方法不能被其他文件直接访问。

  • 举例

using System;

// 全局方法
void PrintMessage(string message)
{
    Console.WriteLine(message);
}

public class Program
{
    public static void Main()
    {
        PrintMessage("Hello from global method!"); // 调用全局方法
    }
}

4.1.2 类、结构 的成员函数

  • 举例
public class MyClass
{
    public void MyMethod()
    {
        Console.WriteLine("Hello from MyClass!");
    }
}

public class Program
{
    public static void Main()
    {
        MyClass obj = new MyClass();
        obj.MyMethod(); // 调用类中的方法
    }
}

4.1.3 函数中定义函数(局部函数)

  • 举例
public class Program
{
    public static void Main()
    {
        int CalculateSum(int a, int b)
        {
            return a + b;
        }

        int result = CalculateSum(5, 3);
        Console.WriteLine(result); // 输出 8
    }
}

4.1.4 匿名函数 & lambda 表达式

  • 匿名函数:一种没有名称的函数,用于委托的实现。

  • Lambda 表达式:一种更简洁的匿名函数语法,用于委托或事件处理。

  • 预定义的委托类型

    • Action:预定义的委托类型,表示没有返回值的方法。
    • Func:预定义的委托类型,表示有返回值的方法。
  • 举例

using System;

public class Program
{
    public static void Main()
    {
        Action myAction = delegate ()
        {
            Console.WriteLine("Hello from anonymous method!");
        };

        myAction(); // 调用匿名方法

        // 使用 Lambda 表达式
        Action myLambda = () => Console.WriteLine("Hello from Lambda!");
        myLambda(); // 调用 Lambda 表达式
    }
}

4.2 自定义委托

  • 用于定义方法的签名,可以将方法作为参数传递,实现回调和事件处理。
  • 类似于 c++ 中的 函数指针
  • 举例
using System;
using System.Collections.Generic;

// 定义一个委托,表示对一个整数的操作
public delegate void ProcessItem(int item);

public class Program
{
    // 一个方法,接受一个列表和一个委托
    public static void ProcessList(List<int> list, ProcessItem process)
    {
        foreach (int item in list)
        {
            process(item); // 调用委托
        }
    }

    // 一个具体的方法,用于打印整数
    public static void PrintItem(int item)
    {
        Console.WriteLine(item);
    }

    public static void Main()
    {
        List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };

        // 将 PrintItem 方法赋给委托
        ProcessItem process = PrintItem;

        // 调用 ProcessList 方法,传入委托
        ProcessList(numbers, process);
    }
}

4.3 泛型

  • 用于定义通用的类、方法或接口,通过类型参数实现类型安全和代码复用。
  • 类似于 c++ 中的模板
  • 举例
void Swap<T>(ref T a, ref T b)
{
    T temp = a;
    a = b;
    b = temp;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值