- ref与out之间的区别:
ref 传的参数必须要先初始化,out不必
ref传进去的参数在函数内部可以直接使用,而out不可
out必须在离开函数前赋值
- 装箱:
对值类型在堆中分配一个对象实例,并将该值复制到新的对象中。按三步进行。
第一步:新分配托管堆内存(大小为值类型实例大小加上一个方法表指针和一个SyncBlockIndex),SyncBlockIndex作用
是指示线程同步状态
第二步:将值类型的实例字段拷贝到新分配的内存中。
第三步:返回托管堆中新分配对象的地址。这个地址就是一个指向对象的引用了。
拆箱:
检查对象实例,确保它是给定值类型的一个装箱值。将该值从实例复制到值类型变量中。 - 扩展方法:被定义为静态方法,它们的第一个参数指定该方法作用于哪个类型,并且该参数以this修饰符为前缀
- 静态类以static声明,指示它只包含静态成员,不包含构造函数,不能被继承可以有静态构造函数,不能有参数,只运行一次,用于初始化静态成员,但我们没法直接调用,而是调用时由CLR自动调用
- readonly:运行时常量,且只能定义类成员变量,可以根据上下文逻辑进行赋值,只能赋值常量
const:编译时常量,编译时已确定 - c#结构体是值类型,特性如下:
所有结构都从Object类派生,不能从其他类或者结构派生,也不能作为其他类或结构的基类。
结构中的字段默认是私有的,并且结构的字段不能在声明时显示初始化。
结构可以有一个或多个构造方法,但是不允许自己定义默认构造函数,而且编译器要求自定义构造函数都要初始化结构的所有字段。
结构的默认构造函数将所有值类型的字段设为0,所有引用类型的字段设为空引用 - try中有return语句,finally中的语句也会执行,在return后运行
- c# 声明了abstract方法的类必须是abstract 方法,abstract方法必须没有实现且必须被继承类实现
- virtual 关键字用于修饰方法、属性、索引器或事件声明,并使它们可以在派生类中被重写,virtual方法必须有实现,virtual 修饰符不能与 static、abstract, private 或 override 修饰符一起使用
- Action:无返回值类型的泛型委托
Func:有返回值类型的泛型委托,最后一个参数是返回类型
Predicate:返回bool型的泛型委托 - params指定可变参数,方法声明中只允许一个params关键字,之后不能再有参数
- 泛型中的静态成员在相同封闭类间共享,在不同封闭类间不共享,例如下面a和b是相同封闭类型,与c不是
stack<int> a = new stack<int>(); stack<int>b= new stack<int>(); stack<long> c= new stack<long>();
当一般方法与泛型方法具有相同签名时会覆盖泛型方法,泛型参数可以有约束
约束
说明
T:结构
类型参数必须是值类型。 可以指定除 Nullable 以外的任何值类型。
T:类
类型参数必须是引用类型;这一点也适用于任何类、接口、委托或数组类型。
T:new()
类型参数必须具有无参数的公共构造函数。 当与其他约束一起使用时,new()class="Apple-converted-space"> 约束必须最后指定。
T:<基类名>
类型参数必须是指定的基类或派生自指定的基类。
T:<接口名称>
类型参数必须是指定的接口或实现指定的接口。 可以指定多个接口约束。 约束接口也可以是泛型的。
T:U
为 T 提供的类型参数必须是为 U 提供的参数或派生自为 U 提供的参数。
- 应用程序域:在一个进程中可以包含多个应用程序域,一个应用程序域可以装载一个可执行程序(*. e xe )或者
多个程序集(*. d l l )。这样可以使应用程序域之间实现深度隔离,即使进程中的某个应用程序域出现错误,也不会影响
其他应用程序域的正常运作。 - 类继承了INotif yPropertyChanged,类中的属性如果跟控件绑定了, 那么PropertyChanged事件 属性就会被自动
赋值,属性变了后可以出发PropertyChanged事件