• [C#1] 6方法


    1.实例构造器[.ctor]

    默认情况下,对于引用类型,如果我们没有显示的定义实例构造器,则C#编译器会为我们定义一个无参的公有实例构造器。 一个类的实例构造器在访问基类的继承字段之前,必须调用基类的实例构造器,C#编译器会自动产生对基类默认构造器的调用代码。

    特殊情况下类型实例的创建不会调用实例构造器:反序列化一个对象时、调用Object的MemberwiseClone方法克隆对象时。

    C#值类型不允许定义无参的构造器,CLR允许这么做

    2.类型构造器[.cctor]

    类型构造器又称静态构造器。C#只允许一个静态构造器,不允许有访问修饰符[默认private]不能有参数。 静态构造器由CLR负责,一旦被调用,那么在整个应用程 序域[AppDomain]的生命周期内就不再被用;静态构造器不应该调用基类的静 态构造器,不需要这样做是因为基类的静态成员并不被派生类所继承。但是我们看 到的是派生类内部引用可基类的静态字段,事实上这不是继承而是编译时静态绑定, 其他的静态成员也是如此的。

    3.操作符重载方法[operator]

    CLR对操作符一无所知,它就不认识什么是操作符。但是却规范了编程语言应 该怎么重载操作符,对CLR而言,重载操作符仅仅是一些方法。如下代码:

    class MyType
    {
        public static MyType operator +(MyType mt1, MyType mt2)
        {
            //....
        }
    }

    编译器会产生一个名为op_Addition的方法,该方法上有一个specialname标记,表 示这是一个特殊的方法。当编译器看到源代码中的“+”时,就会去看其中的操作数据 类型中有哪一个定义了参数类型和操作类型兼容的、名为op_Addition的specialname 方法。如果存在就产生调用该方法的代码,如果不存在就出现编译错误了。

    一些核心 的FCL类型并没有定义任何操作符重载方法(Decimal除外),因为 CLR直接提供了IL 指令支持直接操作这些类型。可以避免些性能的损失,因为如果提供了方法,最终还是 调用的IL指令,所以FCL的核心类型(如 int,byte...)就省去了这些操作符重载方法

    4.转换操作符方法[implicit、explicit]

    有些时候,我们需要将一个类型的对象转化为另一个类型的对象。当源类型和 目标类型都是编译器认识的基元类型时,编译器将知道产生必要的代码来执行这样 的转化[如Byte转为Int32]。但是当有一个类型不是编译器认为的基元类型时 [MyType转为Int32],编译器将不知道怎样执行转化。为了试这些转化成为可能,须写如下代码:

     1 class MyType
     2 {
     3     private double _value;
     4     public MyType() { }
     5     public MyType(int value)
     6     {
     7         this._value = value;
     8     }
     9     public MyType(double value)
    10     {
    11         this._value = value;
    12     }
    13     public int ToInt()
    14     {
    15         return checked((int)this._value);
    16     }
    17     public double ToDouble()
    18     {
    19         return this._value;
    20     }
    21     //由int隐式转换为MyType
    22     public static implicit operator MyType(int value)
    23     {
    24         return new MyType(value);
    25     }
    26     //由double隐式转换为MyType
    27     public static implicit operator MyType(double value)
    28     {
    29         return new MyType(value);
    30     }
    31     //由MyType显示返回一个int
    32     public static explicit operator int(MyType myType)
    33     {
    34         return myType.ToInt();
    35     }
    36     //由MyType显示返回一个double
    37     public static explicit operator double(MyType myType)
    38     {
    39         return myType.ToDouble();
    40     }
    41     public override string ToString()
    42     {
    43         return this._value.ToString();
    44     }
    45 }

    测试代码:

    static void Main(string[] args)
    {
        MyType mt1 = 100;//int隐式转为MyType
        MyType mt2 = 100.06d;//double隐式转为MyType
        Console.WriteLine(mt1);
        Console.WriteLine(mt2);
        int imt1 = (int)mt1;//将MyType显式转为int
        double imt2 = (double)mt2;//将MyType显式转为double
        Console.WriteLine(imt1);
        Console.WriteLine(imt2);
    }

    结果如下:

    转换操作符方法必须为public和static.上述四个静态方法会被编译成如下代码:

    方法明总是为op_Implicit和op_Explicit.但是我们发现前两个方法签名除了返回类型不同之外其他完全相同。 这是因为CLR支持一个类型定义多个只有返回值类型不同的方法,然而很少有语言可以提供如此的能力,C#就不支持这样做。

    转换学习模 版[System.Decimal类]。

    5.引用参数

    默认情况下。CLR对所有的方法参数都是按值传递的[值类型传值的副本,引< 用类型传引用的副本]。CLR当然也支持按引用的方式传递参数,C#中用out和ref 关键字来支持。这两个关键字告诉编译器产生额外的元数据来表示指定的参数是按 引用的方式传递的[参数的地址,而不是参数本身的值]。

    从IL或者CLR的角度,out和ref实际是一样的。两者的不同是编译器会选择不同 的机制来检测我们代码。out修饰的参数在调用前可以不初始化,并且被调方法不能

    接读取该参数的值,必须在方法返回之前为参数赋值。ref修饰的参数调用前则必须初 始化。

    可以根据out和ref参数进行方法重载,但是它们两个之间[也就是只区分out和ref]不能构成重载。

    6.可变数目参数:[params]

    声明例子:

    //关键字params[System.ParamArrayAttribute的简写]
    //完整写法:[System.ParamArrayAttribute] string[] items
    public static void Show(int num, params string[] items)
    {
        //...
    }

    当编译器检测到方法调用时,会根据指定的方法名检查所有不含ParamArrayAttribute的方法,如果符合条件,调用该方法。如果没有找到符合条件的, 就会查找有ParamArrayAttribute特性的方法看其是否满足调用需求。 如果满足,首先会产生一系列指令来构造数据以及用指定的元素填充数据,完成上述操作后才调用该方法。

    注意只有方法的最后一个参数才可以用params修饰。

    7.虚方法

    virtual关键字修饰的方法称为虚方法,此方法允许派生类型重写该方法。虚方法的重写[override、new]:new表示子类重写了父类的方法,但是它隐藏掉了重写的这一事实[就像是子类重新引入的方法一样,和父类没有任何关系了。显得比较"猥琐",重写了还不要让人知道]。override则显得比较"光明正大"...

  • 相关阅读:
    阿诺尔德给5至15岁孩子出的数学题
    上手机器学习,从搞懂这十大经典算法开始
    海报模板
    测度论--长度是怎样炼成的[zz]
    柯西不是你
    搭建Web部署环境
    搭建jdk环境
    Win10远程桌面 出现 身份验证错误,要求的函数不受支持,这可能是由于CredSSP加密Oracle修正 解决方法
    Web开发技术选型之Java与PHP
    从java到web前端再到php,一路走来的小总结
  • 原文地址:https://www.cnblogs.com/linianhui/p/csharp1_method.html
Copyright © 2020-2023  润新知