tips of c#

2018-09-21  本文已影响0人  魍瞳

基础类型的大小是固定,因为会被映射成内部类型

char    //System.Char 16bit unicode
byte    //System.Int8
short   //System.Int16
int     //System.Int32
long    //System.Int64

可空值类型, 可空值类型不能赋值给普通的值类型

int? i = 0;

ref 参数 用来传引用,传进去的值必须先初始化。

out 参数 用来传出值,但是不需要初始化,但是函数内部要对它赋值。

ref或者out一个引用类型,就类似于指针的指针


struct 和 enum 都是值类型,派生自System.ValueType,值类型都是密封的,即不能被继承

值类型都在分配在栈上面,比较小(小于 16 byte)或者不作为函数参数来传递的类型适合声明成值类型

//System.Object == object
object test;

object 可以用int来赋值

会自动转化成引用类型,也就是把在堆上面申请新的内存并把原来在栈上面的值复制过去

这就是所谓的装箱, 但是拆箱需要强制转型

int i = 10;
object obj = i;
int j = (int)obj;

装箱对于复杂的值类型是有坑的,例如

public struct Test {
    public int a;
    public void ChangeX(int to) {
        x = to;
    }
}

Test t = new Test();
object obj = t;
((Test)obj).ChangeX(10); // 这样obj是不会被改变的,拆箱出来的是一个临时栈变量(一个右值)

所以struct的每个变量最好是readonly的 这样struct就会被作为一个整体来看待

这也是为啥unity里面position的xyz不能单独修改的原因,position属性返回了一个新的Vector3值类型


if (i is Point) // is 判断是不是一种类型

i as Point //as 类似dynamic_cast 如果不是返回null 

enum Number : short { One, Two, Three } //第一个值默认是0 然后递增,默认类型是int

struct:

  1. 不能自己写默认构造函数,系统总会生成一个
  2. 不可以定义的时候初始化
  3. new 出来的会调用构造函数,自己写的构造函数必须把每个成员变量都初始化,这样每个成员变量都是初始化过的

class:

  1. 会自己初始化成员变量,这个初始化是个语法糖,实际会发生在class的构造函数里面,并且在父类的构造函数之前
  2. 可以在定义的时候初始化

可以这样显示的指定复写的是哪个接口的函数,然后通过不同类型的ref来调用不同的实现 但是感觉不是很常用的方法

interface IMachine{
    void hello();
}
interface IMan{
    void hello();
}
class Robot : IMachine, IMan{
    void IMachine.hello(){}
    void IMan.hello(){}
}

abstract class Car {} //抽象类,不能实例化
sealed class Car {} //密封类 不能被继承

public int X {
    get { return this._x; }
    set { this._x = value; }
}
//interface属性
interface IMachine{
    int Name { get; set; }
}
//自动创建 自动生成 this._height
class Robot{
    public int Height { get; set; }
}

delegate 提供了类似函数指针的功能

delegate本身是个类,里面包含了target,method_ptr和用来处理委托链的结构

使用的时候需要new一个然后把函数指针传进去

event这个关键字只用于限制delegate的invoke范围,即只能类内调用

上一篇下一篇

猜你喜欢

热点阅读