我知道这应该是一个超级简单的问题,但我已经在这个概念上挣扎了一段时间。

我的问题是,如何在c#中使用链构造函数?

我第一次上面向对象编程课,所以我还在学习。我不明白构造函数链接是如何工作的,如何实现它,甚至为什么它比没有链接的构造函数更好。

我希望你能给我一些解释的例子。

那么怎么把它们拴起来呢? 我知道这句话是:

public SomeClass this: {0}

public SomeClass
{
    someVariable = 0
} 

但是你怎么处理3个,4个等等?

再说一次,我知道这是一个初学者的问题,但我很难理解,我不知道为什么。


当前回答

“构造函数链”的用途是什么? 可以使用它从另一个构造函数调用一个构造函数。

如何实现“构造函数链”? 在构造函数定义后使用":this (yourProperties)"关键字。例如:

Class MyBillClass
{
    private DateTime requestDate;
    private int requestCount;

    public MyBillClass()
    {
        /// ===== we naming "a" constructor ===== ///
        requestDate = DateTime.Now;
    }
    public MyBillClass(int inputCount) : this()
    {
        /// ===== we naming "b" constructor ===== ///
        /// ===== This method is "Chained Method" ===== ///
        this.requestCount= inputCount;
    }
}

为什么它有用? 重要原因是减少编码,防止重复编码。例如用于初始化属性的重复代码 假设类中的某些属性必须用特定的值初始化(在我们的示例中为requestDate)。类有2个或更多的构造函数。如果没有“构造函数链”,你必须在类的所有构造函数中重复初始化代码。

它是如何工作的?(或者,“构造函数链”中的执行顺序是什么)? 在上面的例子中,方法“a”将首先执行,然后指令序列将返回到方法“b”。 换句话说,上面的代码和下面的代码是相等的:

Class MyBillClass
{
    private DateTime requestDate;
    private int requestCount;

    public MyBillClass()
    {
        /// ===== we naming "a" constructor ===== ///
        requestDate = DateTime.Now;
    }
    public MyBillClass(int inputCount) : this()
    {
        /// ===== we naming "b" constructor ===== ///
        // ===== This method is "Chained Method" ===== ///

        /// *** --- > Compiler execute "MyBillClass()" first, And then continue instruction sequence from here
        this.requestCount= inputCount;
    }
}

其他回答

你是在问这个吗?

  public class VariantDate {
    public int day;
    public int month;
    public int year;

    public VariantDate(int day) : this(day, 1) {}

    public VariantDate(int day, int month) : this(day, month,1900){}

    public VariantDate(int day, int month, int year){
    this.day=day;
    this.month=month;
    this.year=year;
    }

}

构造函数链中还有一个重要的点:顺序。 为什么? 假设你有一个在运行时由框架构造的对象,该框架期望它的默认构造函数。如果你想要在传递值的同时仍然能够在需要的时候传递构造函数参数,这是非常有用的。

例如,我可以有一个支持变量,它被默认构造函数设置为默认值,但具有被覆盖的能力。

public class MyClass
{
  private IDependency _myDependency;
  MyClass(){ _myDependency = new DefaultDependency(); }
  MYClass(IMyDependency dependency) : this() {
    _myDependency = dependency; //now our dependency object replaces the defaultDependency
  }
}

我希望下面的例子能对构造函数链接有所启发。 以我这里的用例为例,你希望用户传递一个目录给你的 构造函数时,用户不知道要传递什么目录,并决定让 您可以分配默认目录。您可以进一步分配一个您认为的默认目录 将工作。 顺便说一句,我在这个例子中使用了LINQPad,以防你想知道*. dump()是什么。干杯

void Main()
{

    CtorChaining ctorNoparam = new CtorChaining();
    ctorNoparam.Dump();
    //Result --> BaseDir C:\Program Files (x86)\Default\ 

    CtorChaining ctorOneparam = new CtorChaining("c:\\customDir");
    ctorOneparam.Dump();    
    //Result --> BaseDir c:\customDir 
}

public class CtorChaining
{
    public string BaseDir;
    public static string DefaultDir = @"C:\Program Files (x86)\Default\";


    public CtorChaining(): this(null) {}

    public CtorChaining(string baseDir): this(baseDir, DefaultDir){}

    public CtorChaining(string baseDir, string defaultDir)
    {
        //if baseDir == null, this.BaseDir = @"C:\Program Files (x86)\Default\"
        this.BaseDir = baseDir ?? defaultDir;
    }
}

所有这些答案都很好,但我想对构造函数的初始化稍加说明。

class SomeClass {
    private int StringLength;
    SomeClass(string x) {
         // this is the logic that shall be executed for all constructors.
         // you dont want to duplicate it.
         StringLength = x.Length;
    }
    SomeClass(int a, int b): this(TransformToString(a, b)) {
    }
    private static string TransformToString(int a, int b) {
         var c = a + b;
         return $"{a} + {b} = {c}";
    }
}

尽管这个例子没有这个静态函数也可以解决,但是静态函数允许更复杂的逻辑,甚至可以从其他地方调用方法。

“构造函数链”的用途是什么? 可以使用它从另一个构造函数调用一个构造函数。

如何实现“构造函数链”? 在构造函数定义后使用":this (yourProperties)"关键字。例如:

Class MyBillClass
{
    private DateTime requestDate;
    private int requestCount;

    public MyBillClass()
    {
        /// ===== we naming "a" constructor ===== ///
        requestDate = DateTime.Now;
    }
    public MyBillClass(int inputCount) : this()
    {
        /// ===== we naming "b" constructor ===== ///
        /// ===== This method is "Chained Method" ===== ///
        this.requestCount= inputCount;
    }
}

为什么它有用? 重要原因是减少编码,防止重复编码。例如用于初始化属性的重复代码 假设类中的某些属性必须用特定的值初始化(在我们的示例中为requestDate)。类有2个或更多的构造函数。如果没有“构造函数链”,你必须在类的所有构造函数中重复初始化代码。

它是如何工作的?(或者,“构造函数链”中的执行顺序是什么)? 在上面的例子中,方法“a”将首先执行,然后指令序列将返回到方法“b”。 换句话说,上面的代码和下面的代码是相等的:

Class MyBillClass
{
    private DateTime requestDate;
    private int requestCount;

    public MyBillClass()
    {
        /// ===== we naming "a" constructor ===== ///
        requestDate = DateTime.Now;
    }
    public MyBillClass(int inputCount) : this()
    {
        /// ===== we naming "b" constructor ===== ///
        // ===== This method is "Chained Method" ===== ///

        /// *** --- > Compiler execute "MyBillClass()" first, And then continue instruction sequence from here
        this.requestCount= inputCount;
    }
}