sharp privado example español ejemplo constructors c# constructor constructor-chaining

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



private constructor (8)

Sé que esto es supuestamente una pregunta super simple, pero he estado luchando con el concepto desde hace algún tiempo. Mi pregunta es, ¿cómo encadena a los constructores en c #? Estoy en mi primera clase de 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é que con dos va

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

Pero, ¿cómo lo haces con tres, cuatro y así sucesivamente?

Una vez más, sé que esta es una pregunta para principiantes, pero estoy luchando para entender esto y no sé por qué.


¿Estás preguntando por 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; } }


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 aprobar y decide permitirle asignar el directorio predeterminado. da un paso adelante y asigna un directorio predeterminado que cree que funcionará.

Por cierto, usé 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; } }


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

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 permitirte crear el objeto con solo un nombre, o solo un nombre y una dirección. Si crea una instancia con solo un nombre, se enviará un valor predeterminado, string.Empty hasta el nombre y la dirección, que luego envía un valor predeterminado para Postcode al constructor final.

Al hacerlo, estás reduciendo la cantidad de código que has escrito. En realidad, solo un constructor tiene código, no te estás repitiendo, así que, por ejemplo, si cambias el nombre de una propiedad a un campo interno, solo necesitas cambiar un constructor, si configuras esa propiedad en los tres constructores. Eso sería tres lugares para cambiarlo.


Hay otro punto importante en el encadenamiento de constructores: el orden. ¿Por qué? Digamos que tiene un objeto que está siendo construido en tiempo de ejecución por un marco que espera que sea su constructor predeterminado. Si desea poder pasar valores mientras aún tiene la capacidad de pasar argumentos de constructor cuando lo desea, 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 ser sobrescrita.

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


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

Sin embargo, si te quedas en 4.0, tengo buenas noticias. ¡Ahora puedes tener un solo 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 los valores predeterminados se han establecido.

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


Tengo una clase de diario y no escribo 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; }


Utiliza la sintaxis 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 los constructores en el tipo base(...) usando la 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) {...}

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

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


¿Cuál es el uso de "Constructor Chain"?
Lo usas para llamar a un constructor de otro constructor.

¿Cómo se puede implementar la "Cadena Constructor"?
Use la palabra clave ": this (yourProperties)" después de la definición de 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 la reducción de la codificación y la prevención de códigos duplicados. como código repetido para la propiedad de inicialización Supongamos que alguna propiedad de la clase debe inicializarse con un valor específico (en nuestro ejemplo, requestDate). Y la clase tiene 2 o más constructores. Sin la "Cadena de constructores", debe repetir el código de inicialización en todos los conectores de la 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 instrucciones volverá al método "b". En otras palabras, el código anterior es igual al 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; } }