C# 7.0 核心技术指南——随手摘录

2021-03-09 01:26

阅读:333

标签:comment   泛型   生成   sealed   intern   初始化   sea   方法   访问权限   

C# 类

字段

readonly

 

自动属性

编译器会自动生成一个后台私有变量,字段名称由编译器生成且无法引用

 

属性初始化器

public decimal CurrentPrice{ get;set; } = 123;

 

 

重载构造器

当构造器调用另一个构造器,被调用的构造器先执行

 

解构器

名字必须为Deconstruct

public void Deconstruce(out float width, out float height){
width = Width;
height = Height;
}

调用

(float width, float height) = rect;

 

字段初始化

字段的初始化按声明的先后顺序,在构造器之前执行

 

方法重载

Foo(int)
Foo(out int) 或Foo(ref int) 两个不能同时出现在一个类中

 

索引器的实现

定义一个为this 的属性;,并将参数定义放在一对方括号中

class Sentence
{
   string[] words = "xcxfasdfasdfa".Split()
   
public string this[int wordNum]{
       get{return words[wordNum];}
       set{words[wordNum] = value;}
  }
}

 

静态构造器

每个类型的静态构造器只会执行一次

触发条件

  • 实例化类型

  • 访问类型的静态成员

静态字段初始化按照字段声明的先后顺序运行

 

部分类型

允许一个类型分开进行定义,典型的做法是分开在多个文件中

部分类型可以包含部分方法(partial method) ,形成类型钩子

 

nameof

返回任意符号的字符串名称(类型,成员,变量)

 

继承

多态

引用是多态的

意味着x类型的变量可以指向x子类的对象

 

类型转换和引用转换

  • 隐式向上转换为基类的引用

  • 显示向下转换为子类的引用 (失败抛出 InvalidCastException )

向上转换仅影响引用,而不会影响被引用的对象。而向下转换必须是显示,有可能导致运行时错误

 

as 运算符

as 向下类型转换时出错时返回null

 

is 运算符

检测转换是否能够成功 返回bool

 

is 与 模式变量
if (as is Stock s){
Console.WriteLine(s.SharesOwned);
}

 

虚函数成员

允许Override重新,调用base 引用父类实现

 

抽象类与抽象成员

abstract 不能直接实例化

抽象成员不提供实现,除非子类也声明为抽象类,否则必须由子类提供;

 

隐藏继承成员

public class A {public int Counter = 1;}
public class A : B {public int Counter 2;}

A的引用(在编译时)绑定到 A.Counter

B 的引用(在编译时)绑定到B.Counter

需要故意隐藏一个成员时,使用 new 修饰符明确的隐藏的意图

 

 

new 与重写的区别

    public class BaseClass
  {
       public virtual void Foo()
      {
           Console.WriteLine("BaseClass.Foo");
      }
  }
?
   public class Overrider : BaseClass
  {
       public override void Foo()
      {
           Console.WriteLine("Overrider.Foo");
      }
  }
?
   public class Hider : BaseClass
  {
       public new void Foo()
      {
           Console.WriteLine("Hider.Foo");
      }
  }
?
//输出
BaseClass b1 = over;
           over.Foo();  //Overrider.Foo
           b1.Foo();   //Overrider.Foo
           var h = new Hider();
           BaseClass b2 = h;
           h.Foo(); //Hider.Foo
           b2.Foo(); //BaseClass.Foo

 

密封函数和类

使用sealed关键字密封其实现

 

base关键字

两个重要目的

  • 从子类访问重写或隐藏的基类函数的成员

  • 调用基类的构造器

 

构造器和继承

构造器和字段初始化的顺序
  1. 初始化子类字段,计算被调用的基类构造函数中的参数,再初始化基类的字段

  2. 从基类到子类构造器方法体的执行

 

object 类型

装箱和拆箱

装箱:是将值类型实例转换为引用类型实例的行为

int x = 9;
object obj = x; //Box the int

拆箱:把object类型转换成原始的值类型

拆箱需要显示类型转换,运行时将检查提供的值类型和真正的对象类型是否匹配

出错异常:InvalidCastException

装箱时把值类型的实例复制到新对象中,而拆箱是把对象的内容复制回值类型的实例中

 

GetType 和 typeof
  • 在实例类型上调用GetType方法

  • 在类型名称上使用typeof运算符

 

object
public class Object{
public Object();

public extern Type GetType();

public virtual bool Equals(object obj);
public static bool Equals(object objA, object objB);
public static bool ReferenceEquals(object objA, object objB);

public virtual int GetHashCode();

public virtual string ToString();

protected virtual void Finalize();
protected extern object MemberwiseClone();
}

 

结构体

值类型,不支持派生

不支持以下成员

  • 无参数的构造器

    隐式包含一个无法重写的无参数构造器

    定义结构体的构造器,必须显示为每一个字段赋值

  • 字段初始化器

  • 终结器

  • 虚成员或protect成员

 

访问权限修饰符

public
internal --支持友元程序集
private
protected

友元程序集

[assembly: internalsVisibleTo ("Friend")]

 

接口

  • 接口的成员都是隐式抽象的。相反,类可以包含抽象的成员和有具体实现的成员

  • 一个类(结构体)可以实现多个接口,而一个类只能够继承一个类,结构体不支持类

接口成员总是隐式public

 

接口可以从其他接口派生

 

显示接口实现

具体接口名称.方法

 

虚方法实现接口成员

默认情况下,实现的接口成员是密封的

为了重写,必须在基类中将其标识为virtual

显示实现的接口不能标识为virtual,但是可以被重新实现(reimplemented)

 

在子类中重新实现接口

重新继承接口,并重新实现

 

将结构体转为接口时会引发装箱,但调用结构体的接口成员时不会引发装箱

 

枚举类型

一种特殊的值类型,在枚举类型中定义一组命名的数字常量

  • 对应的数值都是int类型

  • 按照枚举成员的生命顺序,自动按照0、1、2···进行常量赋值

 

枚举类型转换

枚举类型的实例可以与他对应的整数值相互显示转换

 

标志枚举类型

[Flags]

 

嵌套类型

  • 可以访问包含它的外层类型中的私有成员,以及外层类所能访问的所有内容

  • 声明上可以使用所有的访问权限修饰符

  • 嵌套类型的默认可访问性是private 而不internal

  • 从外层类以外访问嵌套类型,需要使用外层类型名称进行限定(类似与访问静态变量)

 

 

泛型

类型占位符 T

开放类型

 

为什么需要泛型?

代码能够跨类型复用

 

泛型方法

只有引入类型参数的方法才可以归为泛型方法

 

声明类型参数

使用多个类型参数,每一个类型参数都使用T作为前缀,后面跟一个更具描述性的名称

 

typeof 和未绑定泛型的类型

Type a2 = typeof ( A )

 

泛型的默认

default(T)

 

泛型的约束

where T : base-class //base-class contraint
where T : interface //接口
where T : class //引用类型
where T : struct //值类型
where T : new() //无参数构造器
where U : T //
  • 基类约束要求类型参数必须是子类(或基类)

  • 接口约束要求类型参数必须实现特定的接口

  • 类约束和结构体规定 T 必须是引用类型或者值类型

  • 无参数构造约束要求有一个无参数构造器,可以在T上调用new()

 

继承泛型类型

泛型和非泛型一样可以派生子类

 

自引用泛型声明

一个类型可以使用自身类型作为具体类型来封闭类型参数

public interface IEquatableT> {bool Equals (T obj);}
?
public class Ballon : IquatableBallon>{
   public string Color {get;set;}
   
   public bool Equals(Ballon b){
       if (b == null) return false;
       return b.Color == this.Color;
  }
}

 

静态数据

静态数据对于每一个封闭类型都是唯一的

 

类型参数的转换

数值转换

引用转换

装箱/拆箱转换

自定义转换

 

协变与逆变

仅泛型接口和和泛型委托支持

 

协变

假定 A 可以转换为 B, 如果 X 可以转换为X那么称X有一个协变类型参数

声明协变类型参数

在接口和委托的类型参数上制定 out 修饰符课将其声明为协变参数

public interface IPoppable{ T Pop(); }

由于 out 修饰符,表明了 T 只能用于输出的位置,如果用于写入,编译错误

 

方法中的 out 参数是不支持协变的,由CLR限制

 

 

逆变

与协变相反,允许X 转换为 X

in 修饰符 只允许输入

public interface IPushable { void Push (T obj); }

 

 

 

 

 

C# 7.0 核心技术指南——随手摘录

标签:comment   泛型   生成   sealed   intern   初始化   sea   方法   访问权限   

原文地址:https://www.cnblogs.com/Gilfoyle/p/12770816.html


评论


亲,登录后才可以留言!