vr引擎设计-c#基础第七天

462 阅读13分钟

image.png

函数的几个练习

  1. 题目一 image.png

image.png 2. 题目二

1.gif image.png

/**
 * 汉诺塔递归:每次只能移动一个长方形,并且大的长方形不能在小的长方形之上
 * 算法:递归
 * 第一步:
 *      把n-1个模块 从塔1移动到塔2
 *      把第n个模块 从塔1移动到塔3
 * 第二步:
 *      把n-1个模块 从塔2移动到塔3
 */
            //创建一个函数 这个函数能够将n个圈从xx移到xx  
            // f(n)=>f(n)
            static void hano(int n, string start, string middle, string end)
            {
                //留出口  
                if (n == 1)   //  hano(n)
                {
                    Console.WriteLine("从{0}经过{1}移到{2}", start, middle, end);
                    return;
                }

                hano(n - 1, start,end,middle); //n-2
                hano(1, start, middle, end);
                //Console.WriteLine("从{0}移到{1}", start, end);
                hano(n - 1, middle, start, end);  // hano(n-1)



            }
            hano(3, "A", "B", "C");

一、常量

image.png

二、枚举类型

1.基本语法结构

image.png

2.使用枚举类型表示王者荣耀中的游戏角色(法师,坦克,射手,战士)

3.使用枚举类型表示周一到周日(周一,周二...周日)

4.注意每个枚举中的值都对应一个整数从0开始,所以枚举类型可以和整型类型互相转换

image.png

5.枚举类型也可以和字符串进行转换

image.png

6.枚举练习

  • 提示用户选择一个qq在线状态,分别有OnLine 1,OffLine 2,Busy 3 3种状态,输入对应 状态的编号打印出 您选择的2qq状态是xx(提示:使用switch)

image.png

7.获取枚举类型中的名称和编号值

 //怎么遍历枚举中的名字    
 foreach(string i in Enum.GetNames(typeof(Role)))  //Enum类中的GetNames方法 传入要遍历的枚举类型的名字   
 {
    Console.WriteLine(i);
 }
            //遍历枚举中对应名字后面的值   
 foreach (int i in Enum.GetValues(typeof(Role)))  //Enum类中的GetValues方法 获取枚举中对应名称后面的值  
 {
    Console.WriteLine(i);
 }

三、结构体

1.如果想要表示学生的信息

学生的信息有:年龄,爱好,姓名,身份证等等,如果想要这样我就要创建很多变量,而且变量都是分散,不好维护,下次想再编写下一个学生的信息又得重新创建一堆变量

2.结构体基本语法

image.png

image.png

3.给结构体中的变量赋值

image.png

四、异常处理

image.png

五、委托的定义和声明

1. 委托是什么?

其实,我一直思考如何讲解委托,才能把委托说得更透彻。说实话,每个人都委托都有不同的见解,因为看问题的角度不同。个人认为,可以从以下2点来理解:

(1) 从数据结构来讲,委托是和类一样是一种用户自定义类型**。

 (2) 从设计模式来讲,委托(类)提供了方法(对象)的抽象。

既然委托是一种类型,那么它存储的是什么数据?

我们知道,委托是方法的抽象,它存储的就是一系列具有相同签名和返回回类型的方法的地址。调用委托的时候,委托包含的所有方法将被执行。

 

2. 委托类型的定义

委托是类型,就好像类是类型一样。与类一样,委托类型必须在被用来创建变量以及类型对象之前声明。

delegate void MyDel(int x);

委托类型声明:

(1) 以deleagate关键字开头。

(2)返回类型+委托类型名+参数列表。

 

3. 声明委托变量

MyDel del1,del2;

 

4. 初始化委托变量

(1) 使用new运算符

new运算符的操作数的组成如下:

  • 委托类型名
  • 一组圆括号,其中包含作为调用列表中的第一个成员的方法的名字。方法可以是实例方法或静态方法。
del1 = new MyDel( myInstObj.MyM1 );
del2 = new MyDel( SClass.OtherM2 );

(2)使用快捷语法

快键语法,它仅由方法说明符构成。之所以能这样,是因为在方法名称和其相应的委托类型之间有隐式转换。

del1 = myInstObj.MyM1;
del2 = SClass.OtherM2;

 

5. 赋值委托

 由于委托是引用类型,我们可以通过给它赋值来改变包含在委托变量中的方法地址引用。旧的引用会被垃圾回收器回收。

MyDel del;
del = myInstaObj.MyM1; //委托初始化
del = SClass.OtherM2;//委托重新赋值,旧的引用将被回收

 

6. 组合委托

 委托可以使用额外的运算符来组合。这个运算最终会创建一个新的委托,其调用列表是两个操作数的委托调用列表的副本的连接。

委托是恒定的,操作数委托创建后不会被改变。委托组合拷贝的是操作数的副本

MyDel del1 = myObj.MyMethod;
MyDel del2 = SClass.OtherM2;
MyDel del3 = del1 + del2;   //组合调用列表

 

7. 委托加减运算

可以使用+=运算符,为委托新增方法。

同样可以使用-=运算符,为委托移除方法。

MyDel del = myObj.MyMethod;
del += SClass.OtherM2; // 增加方法
del -= myObj.MyMethod; // 移除方法

 

8. 委托调用

委托调用跟方法调用类似。委托调用后,调用列表的每个方法将会被执行。

在调用委托前,应判断委托是否为空。调用空委托会抛出异常。

if(null != del)
{
     del();//委托调用
}

 

9. 匿名方法

匿名方法是在初始化委托时内联声明的方法。

基本结构:

deleage( 参数 ) { 语句块 }

例如:

delegate int MyDel (int x); //定义一个委托 

MyDel del = delegate( int x){ return x; };

从上面我们可以看到,匿名方法是不会显示声明返回值的

 

10. Lambda表达式

Lambda表达式主要用来简化匿名方法的语法。在匿名方法中,delegate关键字有点多余,因为编译器已经知道我们将方法赋值给委托。通过几个简单步骤,我们就可以将匿名方法转换为Lambda表达式:

  • 删除delegate关键字
  • 在参数列表和匿名方法主体之间防Lambda运算符=>。Lambda运算符读作"goes to"。
MyDel del = delegate( int x) { return x; };//匿名方法
MyDel del2 = (int x) => {return x;};//Lambda表达式
MyDel del3 = x => {return x};//简写的Lambda表达式

六、c#中的关键字

类型

Void

用作方法的返回类型时,void 关键字指定方法不返回值。

在方法的参数列表中不允许使用 void。采用以下形式声明一个无参数的、不返回值的方法:

Ovid SampleMethod();

Var

在方法范围中声明的变量可以具有隐式类型 var。隐式类型的本地变量是强类型变量(就好像您已经声明该类型一样),但由编译器确定类型。 有返回值

引用类型

Class

类是使用关键字 class 声明的

委托

委托类型的声明与方法签名相似,有一个返回值和任意数目任意类型的参数: 
public delegate void TestDelegate(string message);

public delegate int TestDelegate(MyType m, long num);

delegate 是一种可用于封装命名或匿名方法的引用类型。委托类似于 C++ 中的函数指针;但是,委托是类型安全和可靠的。

接口

接口只包含方法、属性、事件或索引器的签名。成员的实现是在实现接口的类或结构中完成的

Object

object 类型在 .NET Framework 中是 Object 的别名。在 C# 的统一类型系统中,所有类型(预定义类型、用户定义类型、引用类型和值类型)都是直接或间接从 Object 继承的。可以将任何类型的值赋给 object 类型的变量。将值类型的变量转换为对象的过程称为“装箱”。将对象类型的变量转换为值类型的过程称为“取消装箱”。

String

string 类型表示零或更多 Unicode 字符组成的序列。string 是 .NET Framework 中 String 的别名。

尽管 string 是引用类型,但定义相等运算符(== 和 !=)是为了比较 string 对象(而不是引用)的值。这使得对字符串相等性的测试更为直观。

修饰符

Override

要扩展或修改继承的方法、属性、索引器或事件的抽象实现或虚实现,必须使用 override 修饰符。

Virtual

virtual 关键字用于修饰方法、属性、索引器或事件声明,并使它们可以在派生类中被重写。例如,此方法可被任何继承它的类重写。

volatile

volatile 关键字指示一个字段可以由多个同时执行的线程修改。声明为 volatile 的字段不受编译器优化(假定由单个线程访问)的限制。这样可以确保该字段在任何时间呈现的都是最新的值。

unsafe

unsafe 关键字表示不安全上下文,该上下文是任何涉及指针的操作所必需的。

static

使用 static 修饰符声明属于类型本身而不是属于特定对象的静态成员。static 修饰符可用于类、字段、方法、属性、运算符、事件和构造函数,但不能用于索引器、析构函数或类以外的类型。

sealed

当对一个类应用 sealed 修饰符时,此修饰符会阻止其他类从该类继承。在下面的示例中,类 B 从类 A 继承,但是任何类都不能从类 B 继承。

readonly

readonly 关键字是可以在字段上使用的修饰符。当字段声明包括 readonly 修饰符时,该声明引入的字段赋值只能作为声明的一部分出现,或者出现在同一类的构造函数中。

extern

extern 修饰符用于声明在外部实现的方法。extern 修饰符的常见用法是在使用 Interop 服务调入非托管代码时与 DllImport 属性一起使用。在这种情况下,还必须将方法声明为 static

event

event 关键字用于在发行者类中声明事件。

const

const 关键字用于修改字段或局部变量的声明。它指定字段或局部变量的值是常数,不能被修改。

abstract

abstract 修饰符可以和类、方法、属性、索引器及事件一起使用。在类声明中使用 abstract 修饰符以指示某个类只能是其他类的基类。标记为抽象或包含在抽象类中的成员必须通过从抽象类派生的类来实现。

访问修饰符

internal

internal 关键字是类型和类型成员的访问修饰符。只有在同一程序集的文件中,内部类型或成员才是可访问的

private

private 关键字是一个成员访问修饰符。私有访问是允许的最低访问级别。私有成员只有在声明它们的类和结构体中才是可访问的

protected

protected 关键字是一个成员访问修饰符。受保护成员在其所在的类中可由派生类实例访问。

public

public 关键字是类型和类型成员的访问修饰符。公共访问是允许的最高访问级别。

abstract 可以和类、方法、属性、索引器及事件一起使用, 
标识一个可以扩展但不能被实体化的、必须被实现的类或方法。

as 一个转换操作符,如果转换失败,就返回null。

base 用于访问被派生类或构造中的同名成员隐藏的基类成员。

catch 定义一个代码块,在特定类型异常抛出时,执行块内代码。 
参见try和finally。

checked 既是操作符又是语句。 
确保编译器运行时,检查整数类型操作或转换时出现的溢出。

const 标识一个可在编译时计算出来的变量值,即一经指派不可修改的值。

delegate 指定一个声明为一种委托类型。委托把方法封装为可调用实体, 
能在委托实体中调用。

enum 表示一个已命名常量群集的值类型。

event 允许一个类或对象提供通知的成员,他必须是委托类型。

explicit 一个定义用户自定义转换操作符的操作符, 
通常用来将内建类型转换为用户定义类型或反向操作。 
必须再转换时调用显示转换操作符。

extern 标识一个将在外部(通常不是c#语言)实现的方法。

finally 定义一个代码块,在程序控制离开try代码快后执行。参见try和catch。

fixed 在一个代码块执行时,在固定内存位置为一个变量指派一个指针。

foreach 用于遍历一个群集的元素。

goto 一个跳转语句,将程序执行重定向到一个标签语句。

implicit 一个操作符,定义一个用户定义的转换操作符。 
通常用来将预定义类型转换为用户定义类型或反向操作。 
隐式转换操作符必须在转换时使用。

interface 将一个声明指定为接口类型,即实现类或构造必须遵循的合同。

internal 一个访问修饰符。

namespace 定义一个逻辑组的类型和命名空间。

operator 用来声明或多载一个操作符。

out 标识一个参数值会受影响的参数,但在传入方法时, 
该参数无需先初始化。

params 声明一个参数数组。如果使用,必须修改指定的最后一个参数。 
允许可选参数。

readonly 标识一个变量的值在初始化后不可修改。

ref 标识一个参数值可能会受影响的参数。

sealed 防止类型被派生,防止方法和property被覆载。

sizeof 一个操作符,以byte为单位返回一个值类型的长度。

stackalloc 返回在堆上分配的一个内存块的指针。

struct struct是一种值类型,可以声明常量、字段、方法、property、 
索引器、操作符、构造器和内嵌类型。

throw 抛出一个异常。

try 异常处理代码块的组成部分之一。try代码块包括可能会 
抛出异常的代码。参阅catch和finally关键字。

typeof 一个操作符,返回传入参数的类型。

unchecked 禁止溢出检查。

unsafe 标注包含指针操作的代码块、方法或类。

using 当用于命名空间时,using关键字允许访问该命名空间中的类型, 
而无需指定其全名。也用于定义finalization操作的范围。 
virtual 一个方法修饰符,标识可被覆载的方法。

volatile 标识一个可被操作系统、某些硬件设备或并发线程修改的attribute。

一般的构造函数总是public类型的,如果是private类型的,表明类不能被实例化,这通常用于只含有静态的成员的类。

在派生类中声明对虚方法的重载,要求在声明中加上override关键字,而且不能有new,static或virtual修饰符。

密封类在声明中使用sealed修饰符,这样就可以防止该类被其它类继承。

七、转义字符

image.png