关于c#:`this`和一个类构造函数

`this` and a class constructor

我现在有一个类,我对它的构造函数有点困惑。

1
2
3
4
 public class BarListTracker : GotTickIndicator
 {
    public BarListTracker(BarInterval interval) : this(new BarInterval[] { interval }) { }
 }

这句话是什么意思?


这是构造函数链接。本质上,在执行该构造函数的内容之前,您正在调用另一个构造函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Foo
{
    public Foo()
        : this("Hello")
    {
        Console.Write(" World!");
    }

    public Foo(string text)
    {
        Console.Write(text);
    }
}

new Foo(); //outputs"Hello World!"

因此,在您的BarListTracker中的某个地方,应该有另一个采用BarInterval[]数组或IEnumerable的构造函数,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class BarListTracker : GotTickIndicator
{
    public BarListTracker(BarInterval interval)
        : this(new BarInterval[] { interval })
    {
        //specific initialization for this constructor
    }

    public BarListTracker(BarInterval[] intervals)
    {
        //shared initialization logic for both constructors
    }
}

它将执行主体BarListTracker(BarInterval[]),然后执行主体BarListTracker(BarInterval)

这通常用于减少代码重复。如果您的BarListTracker有一些初始化代码,那么在一个地方编写它并与构造函数共享该逻辑比为每个构造函数重写它更有意义。

此外,它允许您使用基本表达式传入或修改输入参数。因此,在本例中,为了与调用BarListTracker(BarInterval[])构造函数保持一致,它将单个BarInterval interval对象包装为与签名匹配的数组。很可能这只是为程序员提供一个更简单的API的一个便利过载,他们通常只有一个BarInterval来构造跟踪器。


这意味着对BarListTracker的另一个构造函数的调用,它接收一个BarInterval对象数组,并传入一个包含传递给该构造函数的对象的数组。打电话来了

1
var tracker = new BarListTracker(interval);

相当于:

1
var tracker = new BarListTracker(new BarInterval[] { interval });


这意味着当这个类被调用并将值作为一个BarInterval数组传递时,它们是基于类中的另一个构造函数或调用的。在本例中,它不是一个基类,因为否则它将称为: base(...),它是在这个非常相同的类中定义的另一个构造函数。

这是非常常见的,因为您希望以多种不同的方式访问一个类,在这种情况下,他们似乎希望能够在不在代码中设置数组的情况下,一次只发送一个对象。

但是,他们可以做的一件事就是更改另一个构造函数,用: this调用的构造函数是:

1
public BarListTracker(params BarInterval[] interval)

他们甚至不需要第二个构造函数。这是一个更清洁的解决方案,在任何地方都会产生相同的结果。另一个构造函数仍然得到一个数组,如果需要,甚至可以向它传递一个数组:

1
2
var arrOfBarInterval = new BarInterval[] { val1, val2 };
var tracker = new BarListTracker(arrOfBarInterval);

但是,你也可以通过一个:

1
var tracker = new BarListTracker(barInterval);

如果你有能力这样做,我建议你。

需要注意的一点是,: this(...)构造函数在您所在的构造函数之前被调用和执行。在构建逻辑时要记住这一点。


调用此类中的另一个构造函数,如下所示:

1
public BarListTracker(BarInterval[] intervals)

例如,它调用同一类的另一个构造函数

1
2
3
4
5
6
7
8
public class Point{
    public Point(int x, int y){
      this.x=x;
      this.y=y;
    }

    public Point():this(0,0){}
}

如果在你的代码里你打电话

1
var p= new Point();

您将使用定义的无参数构造函数,该构造函数将使用传递给它的参数0,0来调用构造函数。

如果有多个构造函数接受大量参数,并希望为更简单的构造函数提供默认参数,那么这非常有用。


它被称为构造函数链接公共barlistracker(barinterval interval):this(new barinterval[]interval)此关键字用于为构造函数设置链接,即初始化顺序在上面的例子中,您是在初始化barinterval值之前初始化数组元素,即间隔值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 public class BarListTracker
{


    public BarListTracker(BarInterval interval) : this(new BarInterval[] { interval })//Constructor II
    {
        //call after BarListTracker(BarInterval[] barIntervals)
    }

    public BarListTracker(BarInterval[] barIntervals)//Constructor I
    {
        //call first
    }
}


您将拥有另一个以barinterval数组为参数的构造函数。这基本上只是从另一个构造函数调用一个构造函数。另一个可能有用的链接是从另一个构造函数调用一个构造函数