1. 引用类型(class)与值类型(strust)的构造函数(实例构造器)

1,  创建一个引用类型的实例时,首先为实例的数据字段分配内存,然后初始对象的附加字段,最后调用实例构造器来设置对象的初始化状态。

2,  实例构造器用于不能被继承,如果没有定义任何构造器,编译器会指定一个默认的无参数构造器,在它的实现中只是简单的调用基类的无参构造器。(编译器不会为值类型生成默认的构造器,而且不能定义无参构造器)

3,  如果派生类没有显示的调用一个基类的构造器,编译器会自动生成对默认的基类构造器的调用,最终调用到Object的构造器。

4,  不要在构造器中调用会影响构造对象的任何虚方法,因为假如在派生类中进行了重写,会调用重写的实现,但在继承层次中,字段没有完全初始化(很好理解,B:A,A的构造函数中调用虚方法Show(),会调用B中重写的Show(),这个时候B没有初始化,容易出错)。

5,  在多构造器的时候不要造定义字段的时候就赋值,这样的话在每一个构造器编译的时候会生成多次初始化字段的代码。如果有几个初始化的实例字段和大量的重载构造器方法,可考虑在单个构造器中执行这些公共的初始化。(值类型不能为字段设置初始值,而且在定义的有参构造器中必须对字段全部赋值)例如下面这种写法

class CLRClassTest

{

private Int32 a = 2;

private string b = "1d";

private double c = 2.22;

public CLRClassTest()

{ }

public CLRClassTest(string a)

{ }

public CLRClassTest(double b)

{}

}

转换成下面这种写法

class CLRClassTest

{

private Int32 a;

private string b;

private double c;

public CLRClassTest()

{

a = 2;

b = "1d";

c = 2.22;

}

public CLRClassTest(string a)

: this()

{ }

public CLRClassTest(double b)

: this()

{ }

}

1.类型构造器

  1. 类型构造器的作用是设置类型的初始化状态,类型构造器没有参数,写法如下

class SomeRefType

{

static SomeRefType()

{

//SomeRefType被首次访问时,会执行这里的代码

}

}

  1. 定义类型构造器类似于定义无参实例构造器,区别在于必须标记为static,而且默认为私有,不能设置访问修饰符。
  2. 类型构造器中的代码只能访问静态字段,并且常规用途就是初始化这些字段,编译器会自动生成一个类型构造器,如下

class SomeRefType

{

private static Int32 x = 5;

}

默认生成如下代码

class SomeRefType

{

private static Int32 x ;

static SomeRefType()

{

x = 5;

}

}

4. 操作符重载方法(operator)

操作符是指 +,-,*,/,%,>>,|,||等。

如何定义操作符重载请看下面方法。

class CLRComplex

{

public int a;

public static CLRComplex operator +(CLRComplex c1, CLRComplex c2)

{

return new CLRComplex{a=c1.a+c2.a};

}

}

调用操作符重载如下:

CLRComplex a = new CLRComplex() { a = 1 };

CLRComplex b = new CLRComplex() { a = 2 };

CLRComplex c = a + b;

5. 转换操作符(implicit,explicit)

1,  当源类型和目标类型都是基元类型时,编译器自己就知道如何生成转换对象所需要的代码

2,  Implicit关键字告诉编译器为了生成代码来调用方法,不需要再源代码中进行显示转换,explicit关键字告诉编译器只有在发现了显示转换时,才调用方法。

3,  在implicit和explicit关键字之后,要指定operator关键字告诉编译器该方法是一个转换操作符,在operator之后,指定对象要转换成什么类型,在圆括号内指定要从什么类型转,注意使用as或者is操作符时候,永远不会调用这些方法

具体使用方法见下面代码。

/// <summary>

/// 转换操作符

/// </summary>

class CRLRational

{

int a;

float b;

public CRLRational(int num)

{ a = num; }

public CRLRational(float num)

{ b = num; }

public int ToInt()

{

return a;

}

public float ToFloat()

{

return b;

}

public static implicit operator CRLRational(int num)

{

return new CRLRational(num);

}

public static explicit operator CRLRational(float num)

{

return new CRLRational(num);

}

public static implicit operator int(CRLRational r)

{

return r.ToInt();

}

public static explicit operator float(CRLRational r)

{

return r.ToFloat();

}

}

调用方法如下

CRLRational r1 = 5;

CRLRational r2 = (CRLRational)2.5f;

//CRLRational r3 = 2.5f as CRLRational;

//无法通过引用转换、装箱转换、取消装箱转换、包装转换或 null 类型转换将类型“float”转换为“CRLRational”

int a = r1;

float b = (float)r2;

6扩展方法(extension method)

扩展方法的规则和原则

1,  c#只支持扩展方法,不支持扩展属性,扩展事件,扩展操作等,

2,  扩展方法必须在非泛型的静态类中声明,类名没有限制,至少包含一个参数且第一个参数必须为this标记,且只有第一个参数被this标记

3,  扩展方法必须在顶级静态类中定义,不能再嵌套类中定义。

4,  编译器会检查文件作用域中所有的静态类,并扫描它们的所有静态方法来匹配,为了增强性能,避免找到非你所愿的一个扩展方法,编译器要求Using扩展方法的命名空间。

5,  不能给object类型写扩展方法,避免VS智能感知感知到太多垃圾信息。

6,  潜在风险,假如微软提供了一个你扩展方法相同的方法,会调用微软的方法

编译器查找扩展方法的路径,StringBuilder为例:它先检查StringBuilder的所有基类是否提供相应方法,如果存在就调用,如果没有,则继续检查是否有任何静态类定义的对应静态方法,它的第一个参数是和当前用于调用方法的那个表达式的类型匹配的一个类型,而且这个类型必须用this关键字表示,

下面是一个扩展方法的实例:

public static class CLR扩展方法

{

public static int IndexOf(this StringBuilder sb, Char value)

{

for (int i = 0; i < sb.Length; i++)

{

if (sb[i] == value)

return i;

}

return -1;

}

}

StringBuilder sb = new StringBuilder("ffsafsadyaerbgdgasg");

int i = sb.IndexOf('c');

7.分部方法(partial)

对这个不熟,不知道应用场景。以后再补这一块。

【Clr in c#】方法的更多相关文章

  1. 在SQL Server中使用CLR调用.NET方法

    介绍    我们一起来做个示例,在.NET中新建一个类,并在这个类里新建一个方法,然后在SQL Server中调用这个方法.按照微软所述,通过宿主 Microsoft .NET Framework 2 ...

  2. CLR via C#深解笔记四 - 方法、参数、属性

    实例构造器和类(引用类型) 构造器(constructor)是允许将类型的实例初始化为良好状态的一种特殊方法.构造器方法在“方法定义元数据表”中始终叫.ctor. 创建一个引用类型的实例时: #1, ...

  3. [CLR via C#]8. 方法

    一.实例构造器和类(引用类型) 类实例构造器是允许将类型的实例初始化为良好状态的一种特殊的方法. 类实例构造器方法在"方法定义元数据表"中始终叫.ctor(代表constructo ...

  4. 重温CLR(六)方法和参数

    实例构造器和类(引用类型) 构造器是将类型的实例初始化为良好状态的特殊方法.构造器方法在“方法定义元数据表”中始终叫做.ctor(constructor的简称).创建引用类型的实例时,首先为实例的数据 ...

  5. 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_方法执行

    [前言] 方法执行前,CLR 会检测方法内代码引用的所有类型.同时 CLR 会分配一个内部数据结构,用来管理对所有引用的类型的访问. 首次执行方法时,托管程序集会把 IL 转换成本地 CPU 指令,并 ...

  6. C#夯实基础之接口(《CLR via C#》读书笔记)

    一. 接口的类型 接口是引用类型.因此从值类型赋值给接口是需要装箱的.如下所示: class Program { static void Main(string[] args) { ISay catS ...

  7. 《CLR via C#》读书笔记(6)类型和成员基础

    6.1 类型的各种成员 在一个类型中,可以定义0个或者多个以下种类的成员: 常量 常量是在编译时设置其值并且永远不能更改其值的字段.使用常量可以为特殊值提供有意义的名称以代替数字文本,以使代码变得更容 ...

  8. CLR执行模式之程序集代码的执行

    所知IL是与CPU无关的机器语言,其能访问和操作对象类型,并提供指令来创建和初始化对象,调用对象上的虚方法以及直接操作数组对象等,故可视为一种面向对象的机器语言.每种语言的存在都有其存在的价值和原因, ...

  9. 【CLR VIA C#】读书笔记

    工作几年了才看,记录下笔记备忘. 章节 笔记 1.CLR的执行模型 公共语言运行时(Common Language Runtime,CLR) 源代码-->编译器检查语法和分析源代码-->托 ...

  10. CLR via C# - CLR模型

    博客园对markdown支持不佳,错乱移步Github IO 博文 CLR 的执行模型 模块/程序集 1.模块 托管模块组成部分 PE32/PE32+头 : PE即Portable Executabl ...

随机推荐

  1. 【python】pymongo查找某一时间段的数据

    python中实现: 下面代码就是查找2016-09-26 00:00:00 ~ 2016-09-27 00:00:00 时间段的数据 from datetime import datetimefor ...

  2. 让UserControl能显示焦点状态

    'set the control can display the focus status Protected Overrides Sub OnGotFocus(ByVal e As System.E ...

  3. 分享类shareSDK

    1.新浪微博分享时需要注意: [A] 应用信息->基本信息->应用地址 [B] 应用信息->高级信息->OAuth2.0 授权设置 //当使用新浪微博客户端分享的时候需要按照下 ...

  4. 413. Arithmetic Slices

    /**************************Sorry. We do not have enough accepted submissions.*********************** ...

  5. 1.5 STL中大小相等的概念

    1) 2)

  6. entOS7安装iptables防火墙,试验未通过

    CentOS7默认的防火墙不是iptables,而是firewalle. 安装iptable iptable-service #先检查是否安装了iptables service iptables st ...

  7. 学习hibernate @Entity该导入哪个包

    1.在@Entity时很容易顺手导入@org.hibernate.annotations.Entity这个包,结果导致了异常.其实应该导入的是@javax.persistence.Entity Alw ...

  8. jquery学习笔记-----ajax

    $(selector).load( url [,date] [,callback] ) url:请求页面的url地址 date:发送至服务器的key:value数据 callback:请求完成时的回调 ...

  9. 与你相遇好幸运,MongoDB小技巧

    保存为bat方便: "C://Program Files//MongoDB//Server//3.2//bin//mongod.exe" --dbpath=D://corp//db ...

  10. Delphi中函数定义和声明的位置

    当函数(或过程)A定义在函数(或过程)B之前,那么函数B就可以调用函数A,并且编译成功,例如下面的 procedure TForm1.btn1Click(Sender: TObject); 和   f ...