C # constructor de encadenamiento (¿Cómo hacerlo?)

Sé que esta es supuestamente una pregunta muy simple, pero he estado luchando con el concepto desde hace un tiempo. Mi pregunta es, ¿cómo encadenas a los constructores en c #? Estoy en mi primera clase OOP, así que solo estoy aprendiendo. No entiendo cómo funciona el encadenamiento de constructores o cómo implementarlo, o incluso por qué es mejor que simplemente hacer constructores sin encadenar.

Agradecería algunos ejemplos con una explicación.

Entonces, ¿cómo encadenarlos? Sé con dos va:

public SomeClass this: {0} public SomeClass { someVariable = 0 } 

¿Pero cómo lo haces con tres, cuatro y demás?

De nuevo, sé que esta es una pregunta para principiantes, pero estoy luchando por entender esto y no sé por qué.

    Utiliza la syntax estándar (usando this como un método) para elegir la sobrecarga, dentro de la clase:

     class Foo { private int id; private string name; public Foo() : this(0, "") { } public Foo(int id, string name) { this.id = id; this.name = name; } public Foo(int id) : this(id, "") { } public Foo(string name) : this(0, name) { } } 

    entonces:

     Foo a = new Foo(), b = new Foo(456,"def"), c = new Foo(123), d = new Foo("abc"); 

    Tenga en cuenta también:

    • puede encadenar a constructores en el tipo base(...) usando base(...)
    • puedes poner código extra en cada constructor
    • el valor predeterminado (si no especifica nada) es base()

    ¿Para que?”:

    • reducción de código (siempre es algo bueno)
    • necesario para llamar a un constructor base no predeterminado, por ejemplo:

       SomeBaseType(int id) : base(id) {...} 

    Sin embargo, tenga en cuenta que también puede usar los inicializadores de objetos de una manera similar (sin necesidad de escribir nada):

     SomeType x = new SomeType(), y = new SomeType { Key = "abc" }, z = new SomeType { DoB = DateTime.Today }; 

    Solo quiero mencionar un punto válido para cualquiera que busque esto. Si va a trabajar con versiones .NET anteriores a la 4.0 (VS2010), tenga en cuenta que debe crear cadenas de constructores como se muestra arriba.

    Sin embargo, si te estás quedando en 4.0, tengo buenas noticias. ¡Ahora puede tener un único constructor con argumentos opcionales! Simplificaré el ejemplo de la clase Foo:

     class Foo { private int id; private string name; public Foo(int id = 0, string name = "") { this.id = id; this.name = name; } } class Main() { // Foo Int: Foo myFooOne = new Foo(12); // Foo String: Foo myFooTwo = new Foo(name:"Timothy"); // Foo Both: Foo myFooThree = new Foo(13, name:"Monkey"); } 

    Cuando implementa el constructor, puede usar los argumentos opcionales ya que se han establecido los valores predeterminados.

    ¡Espero que hayas disfrutado esta lección! ¡Simplemente no puedo creer que los desarrolladores se hayan quejado sobre el encadenamiento de construcciones y no puedan usar argumentos opcionales predeterminados desde 2004/2005! Ahora ha tardado tanto en el mundo del desarrollo que los desarrolladores tienen miedo de usarlo porque no será compatible con versiones anteriores.

    Esto se ilustra mejor con un ejemplo. Imaging tenemos una clase de persona

     public Person(string name) : this(name, string.Empty) { } public Person(string name, string address) : this(name, address, string.Empty) { } public Person(string name, string address, string postcode) { this.Name = name; this.Address = address; this.Postcode = postcode; } 

    Así que aquí tenemos un constructor que establece algunas propiedades y utiliza el encadenamiento de constructores para permitirle crear el objeto con solo un nombre, o simplemente un nombre y una dirección. Si crea una instancia con solo un nombre, enviará un valor predeterminado, string.Empty al nombre y la dirección, que luego envía un valor predeterminado para el código postal hasta el constructor final.

    Al hacerlo, estás reduciendo la cantidad de código que has escrito. Solo un constructor tiene código, no se está repitiendo, por ejemplo, si cambia Nombre de una propiedad a un campo interno, solo necesita cambiar un constructor, si configurara esa propiedad en los tres constructores. eso sería tres lugares para cambiarlo.

    Tengo una clase de diario y no estoy escribiendo estableciendo los valores una y otra vez

     public Diary() { this.Like = defaultLike; this.Dislike = defaultDislike; } public Diary(string title, string diary): this() { this.Title = title; this.DiaryText = diary; } public Diary(string title, string diary, string category): this(title, diary) { this.Category = category; } public Diary(int id, string title, string diary, string category) : this(title, diary, category) { this.DiaryID = id; } 

    ¿Estás preguntando sobre esto?

      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; } } 

    ¿Qué es el uso de “Cadena Constructor”?
    Lo usa para llamar a un constructor desde otro constructor.

    ¿Cómo se puede implementar “Cadena de Constructor”?
    Use la palabra clave “: this (yourProperties)” después de la definición del constructor. por ejemplo:

     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; } } 

    ¿Por qué es útil?
    Una razón importante es reducir la encoding y evitar el código duplicado. como el código repetido para inicializar la propiedad Supongamos que alguna propiedad en la clase debe inicializarse con un valor específico (en nuestra muestra, requestDate). Y la clase tiene 2 o más constructores. Sin “Cadena de Constructor”, debe repetir el código de inicialización en todos los constractores de clase.

    ¿Como funciona? (O, ¿Qué es la secuencia de ejecución en “Cadena de constructores”)?
    en el ejemplo anterior, el método “a” se ejecutará primero, y luego la secuencia de instrucción volverá al método “b”. En otras palabras, el código anterior es igual a la siguiente:

     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; } } 

    Espero que el siguiente ejemplo arroje algo de luz sobre el encadenamiento de constructores.
    mi caso de uso aquí, por ejemplo, está esperando que el usuario pase un directorio a su constructor, el usuario no sabe qué directorio pasar y decide dejarle asignar el directorio predeterminado. usted intensifica y asigna un directorio predeterminado que cree que funcionará.

    Por cierto, utilicé LINQPad para este ejemplo en caso de que se esté preguntando qué es * .Dump ().
    aclamaciones

     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; } } 

    Hay otro punto importante en el encadenamiento de constructores: orden. ¿Por qué? Digamos que un objeto está siendo construido en tiempo de ejecución por un framework que espera que sea un constructor predeterminado. Si desea poder pasar valores mientras todavía tiene la capacidad de pasar los argumentos del constructor cuando lo desee, esto es extremadamente útil.

    Podría, por ejemplo, tener una variable de respaldo que mi constructor predeterminado establezca en un valor predeterminado, pero que tenga la capacidad de sobrescribirse.

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