①可选参数②构造函数初始化器 (构造函数的重载)③const(常量)和readonly(只读)的异同

可选参数

.net 现在支持可选参数了,顾名思义,可选参数就是在为方法传参时可有可无的参数。

static void Main(string[] args)
{
    MyClass1 mc1 = new MyClass1();
    mc1.OptionFunc(3);//3 1 3
    mc1.OptionFunc(6,3);//6 3 3
    mc1.OptionFunc(6,9,5);//6 9 5

    Console.ReadLine();
}

public class MyClass1
{
    //带可选参数的方法
    public void OptionFunc(int i, int j = 1, int k = 3)
    {
        Console.WriteLine(i);
        Console.WriteLine(j);
        Console.WriteLine(k);
    }
}

如以上代码,虽然OptionFunc方法在定义的时候定义了三个参数,但是它的后两个参数和定义方法时的常见形式不同,它们在定义的时候就已经被赋值了,而类似这样的方法参数就是可选参数。我们在调用这样的方法时,对于其中的可选参数可以选择是否为之传入参数。如果传入参数,则其与普通方法的运作相同,如果不传入参数,则此方法会使用其在定义时声明的值进行操作。
注:可选参数只能写在所有参数的最后。

构造函数初始化器 (构造函数的重载)

有时,一个类会需要多种构造函数,例如:

class Car
{
    private string name;
    private int wheels;

    public Car(string name, int wheels)
    {
        this.name = name;
        this.wheels = wheels;
    }

    public Car(string name)
    {
        this.name = name;
        this.wheels = 4;
    }
}

当我们需要创建多个构造函数的重载时,如果每个都把函数体内的代码重写一份显然有些太过麻烦了,因此以上代码还可以写成如下形式:

class Car
{
    private string name;
    private int wheels;

    public Car(string name, int wheels)
    {
        this.name = name;
        this.wheels = wheels;
    }

    public Car(string name):this(name, 4)
    {
    }
}

这样的话就可以避免多次在方法的重载中编写相同的代码了。然而,事实上就我个人而言我是觉得为这种状况单独设计一条语法有些多余,因为类似这样的重载用下面的写法也完全能够实现和这一样的效果。

public Car(string name)
{
    Car(Car(name, 4));
}

const(常量)和readonly(只读)的异同

const和readonly都有一个特性,那就是只能赋值一次,并且在第一次赋值之后便再不可更改。但是它们有有所不同,具体如下:

①const

static void Main(string[] args)
{
    MyClass1 mc1 = new MyClass1();
    //Console.WriteLine(mc1.constInt);这种调用方法是错误的
    Console.WriteLine(MyClass1.constInt);

    Console.ReadLine();
}

public class MyClass1
{
    public const int constInt = 3;
}

在上述代码中,MyClass1里定义了一个常量constInt。常量在必须在声明的同时赋值,并且常量不可使用static关键字,因为其本身就自带static的效果。观察调用MyClass1中constInt的代码可以看出,即使我们实例化出了一个MyClass1对象,也无法像调用对象的普通属性那样通过这个对象的实例来调用其中的常量。顾名思义,常量就应该是恒常不变的。譬如你设计了一款“体重秤”,那么显然你一定希望这款体重秤在被你设计完成之后能有一个统一的“重力系数(G)”,也就是说,只要制造商是按照你的设计在进行制造,那么不管他造几个这样的秤,即使它们最终可能在外观、体积或者其它方面有所不同,但它们的“重力系数”这项参数一定是相同的。也就是说“重力系数”这个参数是属于“体重秤”的设计原型的,我们无法通过具体的单个体重秤去得知它的重力系数,如果我们想知道这个参数就只能向它的设计者咨询。就像上面的代码,我们无法通过MyClass1的具体事例获取它的constInt常量,如果我们想要获取这个常量就只能通过它的原型(MyClass)直接获取。

②readonly

public class DocumentEditor
{
    public static readonly int MaxDocuments;

    static DocumentEditor()
    {
        //MaxDocuments = DoSomethingToFindOutMaxNumber();
    }
}
static void Main(string[] args)
        {
            MyClass1 mc11 = new MyClass1();
            Console.WriteLine(mc11.randomInt);//12
            Console.WriteLine(MyClass2.randomInt);//12

            Console.ReadLine();//等待3秒后输入

            MyClass1 mc12 = new MyClass1();
            Console.WriteLine(mc12.randomInt);//15
            Console.WriteLine(MyClass2.randomInt);//12

            Console.ReadLine();
        }

        public class MyClass1
        {
            public readonly int randomInt;

            public MyClass1()
            {
                randomInt = DateTime.Now.Second;
            }
        }

        public class MyClass2
        {
            public static readonly int randomInt;

            static MyClass2()
            {
                randomInt = DateTime.Now.Second;
            }
        }

MyClass1中声明了一个非静态的只读属性和一个非静态的构造方法,
MyClass2中声明了一个静态的只读属性和一个静态的构造方法。
在MyClass2中,readonly的使用和之前的const类似,当我们需要调用MyClass2中的静态属性时只能通过MyClass2直接调用。而在MyClass1中,当我们需要调用其中的公有属性时必须通过此类的实例调用。
当我们第一次输出时,”mc11.randomInt”和”MyClass2.randomInt”的输出都是”12”这很容易理解,但当我们第二次输出时,”mc21.randomInt”和”MyClass2.randomInt”的输出却不再相同了,前者成功的加上了我的等待时间(3秒),而后者却依然还是停留在起初的12秒上。这是因为”mc11”和”mc12”都是通过new关键字实例化出来的,因此每当new出一个新的”MyClass1”的实例时,此实例都会调用一次”MyClass1”的构造方法。对于上面的示例代码而言,当我在等待3秒之后又new出了一个新的”MyClass1”实例时,此实例的”randomInt”便会存储为其构造方法所获得的值。但是对于”MyClass2”而言,由于它的构造方法是静态的(static),所以它只会在其第一次被调用时执行,并且无论之后是否又被调用都不再执行,因此在我们第一次输出”MyClass2.randomInt”时,”MyClass2”的构造方法被执行,并将当前时间的秒数赋值给了randomInt,于是我们便看到了两个相同的输出结果(12),但是当我们第二次输出”MyClass2.randomInt”的时候,由于”MyClass2”的静态构造函数不再执行,因此其输出结果仍是第一次的数值(12)。事实上就算”MyClass2”的构造方法不是静态的也没用,因为只要被readonly声明的属性是静态的,那么它就只能被写入一次,而如果此时这个类的构造函数不是static的,那么编译器就会报错,因为这样的话被readonly声明的属性就存在被多次赋值的可能,而这又是不被允许的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值