C#温习

 

C#(GC,装拆箱,ref/out,容器,迭代器),Lua(元表,面向对象),算法,数据结构,渲染(流程),性能优化。

 

1.拆装箱

装箱 box指令

把值类型转换为引用类型

在堆上申请内存空间,把值类型复制到堆上

 

拆箱 unbox.any指令

把引用类型转换为值类型

把存储在堆上的引用类型转化为值类型,赋值给值类型变量

 

2.foreach

foreach语句中,第一次遇到Fruit对象时,调用GetEnumerator()(在Unity老的Mono编辑器中会产生GC,Unity5.6后已经修复),当每次执行到in关键字,调用MoveNext()方法,每次读取数据则调用Current属性。

 

3.结构体

结构体是值类型

结构体的特点:

  1. 结构体可定义构造函数,但不能定义析构函数。不能定义默认的无参构造函数。默认的构造函数是自动定义的,且不能被改变。
  2. 结构体不能继承其他的结构体或类
  3. 结构不能作为其他结构或类的基础结构。
  4. 结构可实现一个或多个接口。
  5. 结构成员不能指定为 abstract、virtual 或 protected。
  6. 当您使用 New 操作符创建一个结构对象时,会调用适当的构造函数来创建结构。与类不同,结构可以不使用 New 操作符即可被实例化。
  7. 如果不使用 New 操作符,只有在所有的字段都被初始化之后,对象才可以被使用。如果所有字段没有完成初始化,引用未赋值的字段会导致编译错误。

类和结构体的区别

  • 类是引用类型,结构体是值类型。
  • 结构体不支持继承。
  • 结构体不能声明默认的无参构造函数。
  • 结构体中声明的字段无法赋予初值,类可以

 

4.值类型和引用类型的区别

值类型在栈上分配空间,由系统自动分配,自动释放

引用类型在堆中分配内存,用new分配

 

string是特殊的引用类型,本质上是一个char类型的数组

string的remove方法,remove(3)从指定下标位置(包含)删除后面的字符串

remove(3,2)从指定位置(包含)删除后面2个字符

string的SubString(4)从指定下标位置(包含)获取后面的子字符串

SubString(4,2)从指定下标位置(包含)获取后面2个字符

 

5.可变参数 params,在有多个可变形参时,可变参数要放在最后

定义:public void Sum(params int[] arr) { }

使用:Sum(1,2,3,4,5);

 

6.析构函数

~Person() { }

1.每个类只能有一个析构方法

2.析构函数不能有返回值

3.析构函数不能有权限修饰符

4.析构函数不能带有参数,更不能重载

 

7.面向对象 面向过程

面向过程:分析解决问题所需要的步骤,然后用函数把这些步骤一步步实现。

面向对象:把构成问题的事物分解成各个对象,建立对象的目的不是为了完成一个个步骤,而是为了描述某个事物在整个解决问题的步骤中的行为。封装,继承和多态

 

8.封装

封装是防止对实现细节的访问,设置使用者的访问权限,并通过访问修饰符来实现。

 (1) Pubilc :任何公有成员可以被外部的类访问。

 (2) Private :只有同一个类中的函数可以访问它的私有成员。

 (3) Protected :该类内部和继承类中可以访问。

 (4) internal : 同一个程序集的对象可以访问。

 (5) Protected internal :3 和 4 的并集,符合任意一条都可以访问。

 

9.抽象

  1. 抽象方法只能出现在抽象类中
  2. 抽象方法在父类中不能实现
  3. 抽象类不能直接实例化
  4. 抽象方法在继承抽象类的子类中必须实现

 

public abstract class Food

{

public abstract void Eat();

}

 

10.虚函数

  1. virtual修饰的方法必须有实现(哪怕仅仅添加一对大括号)
  2. virtual可以被子类重写,也可以不重写
  3. 只有方法和属性才能使用virtual修饰,字段(变量)不能使用virtual修饰

 

public class Food

{

public virtual string Name { get; set;}

public virtual void Eat() { }

}

 

11.接口

  1. 接口默认声明是public的
  2. 接口中定义的方法,不能添加访问修饰符,默认都是public
  3. 接口中的方法,在接口中不能实现
  4. 一旦某个类实现了接口,就必须实现接口中定义的全部成员方法
  5. 不能直接实例化接口
  6. 接口中只能声明方法,属性,事件,索引器。
  7. 接口不能包含字段、构造函数、析构函数、静态成员或常量。

 

public interface Food

{

string Name { get; set; }

void Eat();

}

 

12.内存区域

  • 堆区,手动管理
  • 栈区,系统管理
  • 静态区,程序运行过程中,在内存中一直存在
  • 程序代码区
  • 常量区

 

13.泛型

  1. 使用泛型,可以保证类型安全
  2. 避免拆箱和装箱,提高性能
  3. 提高代码的重用

 

14.索引器

索引器是指允许一个对象可以像数组那样被索引,可以通过方括号[ ]来访问对象的实例。使用this关键字,索引器的行为的声明在某种程度上类似于属性(property)。就像属性(property),您可使用 get 和 set 访问器来定义索引器。但是,属性返回或设置一个特定的数据成员,而索引器返回或设置对象实例的一个特定值。

public T this[int index]

{

set{ }

get{ }

}

 

15.静态成员

我们可以使用 static 关键字把变量定义为静态的。当我们声明一个变量为静态时,意味着无论有多少个类的对象被创建,只会有一个该静态变量的副本。

也可以把一个成员函数声明为 static。这样的函数只能访问静态变量。静态函数在对象被创建之前就已经存在。

 

16.预处理器指令

预处理器指令指导编辑器在实际编译开始之前对信息进行预处理。

#define 允许您定义一个符号,这样,通过使用符号作为传递给 #if 指令的表达式,表达式将返回 true。

 

17.IO-输入和输出

为什么要出现与文件流配套的读写器类型呢?

主要是因为文件流对象(FileStream)在读写字节的效率是相当高的,但是在处理其他类型的数据时会比较麻烦,所以就出现了二进制读写器(BinaryReader和BinaryWriter)和文本读写器(StreamReader和StreamWriter)来解决这一问题。

 

18.委托和事件

区别1:委托是一个类型,事件修饰的是一个对象

区别2:委托可以在声明它的类外部进行调用,而事件只能在类的内部进行调用。

 

19.异步回调

1.调用BeginInvoke开始异步加载, 在 ThreadPool 线程上执行回调方法,而不是在主线程。

2.调用 EndInvoke 来完成异步调用

 

20.序列化和反序列化

序列化是指将对象转换成字节流,从而存储对象或将对象传输到内存、数据库或文件的过程。主要用途是保存对象的状态,以便可以在需要的时候重新创建对象。反向过程就是反序列化。

 

21.反射

反射是程序可以访问、检测、修改它本身状态或行为一种能力。

程序集包括模块,模块包括类型,类型又包括成员。反射可以提供封装程序集、模块和类型的对象。

反射可以动态的创建类型的实例,把类型绑定在现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性。

 

22.特性

特性:描述运行时传递程序中的各种元素(类、方法、结构体等)行为信息的声明性标签。

一个特性,是放置在它应用元素的前面的方括号来描述的。

预定义特性,AttributeUsage是来描述如何使用一个预定义特性类,第一个参数表示可以使用的语言元素,第二个参数表示多用的。

 

23.多线程

  • Thread:自己创建的独立的线程, 优先级高,需要使用者自己管理。
  • ThreadPool:.Net 自己管理, 只需要把需要处理的方法写好, 然后交个.Net Framework, 后续只要方法执行完毕, 则自动退出。
  • Task:C#4.0 以后新增的线程操作方式, 类似 ThreadPool, 但效率测试比ThreadPool略高, Task对多核的支持更为明显,所以在多核的处理器中, Task的优势更为明显。
class Program
{  
    static void Main(string[] args)
    {  //独立创建线程
        Thread t = new Thread(ThreadProcess);
        t.Start(new object());
        
        //线程池
        ThreadPool.QueueUserWorkItem(ThreadProcess, new object());
        //Task方式创建线程
        System.Threading.Tasks.Task.Factory.StartNew(ThreadProcess, new object());

        //需要手动终止,当然现在终止可能线程还未运行完成,
        t.Abort();
    }
    private static void ThreadProcess(object tag)
    {
        int i = 100;
        while (i > 0)
        {
            Console.WriteLine(string.Format("i:{0} ", i));
            Thread.Sleep(10);
            i--;
        }
    }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值