C# конструктор цепочки? (Как это сделать?)
Я знаю, что это якобы супер простой вопрос, но я уже некоторое время борюсь с этой концепцией. Мой вопрос в том, как вы цепляете конструкторы в c#? Я в своем первом классе ООП, так что я просто учусь. Я не понимаю, как работает цепочка конструкторов или как ее реализовать, или даже почему это лучше, чем просто делать конструкторы без цепочки.
Я был бы признателен некоторые примеры с объяснением.
Так как же их сковать? Я знаю с двумя он идет:
public SomeClass this: {0}
public SomeClass
{
someVariable = 0
}
но как это сделать с тремя, четырьмя и так далее?
опять же, я знаю, что это вопрос для начинающих, но я изо всех сил пытаюсь понять это, и я не знаю, почему.
8 ответов:
вы используете стандартный синтаксис (используя
thisкак метод), чтобы выбрать перегрузку,внутри класс: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) { } }затем:
Foo a = new Foo(), b = new Foo(456,"def"), c = new Foo(123), d = new Foo("abc");дополнительные услуги:
- вы можете привязать к конструкторам на базовом типе С помощью
base(...)- вы можете поместить дополнительный код в каждом конструкторе
- по умолчанию (если вы ничего не указываете) является
base()"почему?":
- код сокращение (всегда хорошая вещь)
необходимые для вызова нестандартного базового конструктора, например:
SomeBaseType(int id) : base(id) {...}обратите внимание, что вы также можете использовать инициализаторы объектов аналогичным образом, хотя (без необходимости писать что-либо):
SomeType x = new SomeType(), y = new SomeType { Key = "abc" }, z = new SomeType { DoB = DateTime.Today };
Я просто хочу, чтобы поднять действительную точку для тех, кто ищет это. Если вы собираетесь работать с версиями .NET до 4.0 (VS2010), обратите внимание, что вам нужно создать цепочки конструкторов, как показано выше.
однако, если вы останавливаетесь в 4.0, у меня есть хорошие новости. Теперь у вас может быть один конструктор с необязательными аргументами! Я упрощу пример класса 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"); }при реализации конструктора можно использовать необязательные аргументы, так как установлены значения по умолчанию.
Я надеюсь, вам понравился этот урок! Я просто не могу поверить, что разработчики жалуются на построение цепочки и не могут использовать необязательные аргументы по умолчанию с 2004/2005 года! Теперь это заняло так много времени в мире разработки, что разработчики боятся использовать его, потому что он не будет обратно совместим.
это лучше всего проиллюстрировать на примере. Воображения у нас есть класс человек
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; }Итак, здесь у нас есть конструктор, который устанавливает некоторые свойства и использует цепочку конструкторов, чтобы вы могли создать объект только с именем или просто именем и адресом. Если вы создадите экземпляр только с именем, это отправит значение по умолчанию, string.Пусто до имени и адреса, который затем отправляет значение по умолчанию для почтового индекса до конечного конструктора.
In таким образом, вы уменьшаете количество кода, который вы написали. Только один конструктор на самом деле имеет код в нем, вы не повторяетесь, поэтому, например, если вы меняете имя из свойства во внутреннее поле, вам нужно изменить только один конструктор - если вы установите это свойство во всех трех конструкторах, которые будут тремя местами для его изменения.
У меня есть класс дневника, и поэтому я не пишу установку значений снова и снова
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; }
что такое использование "конструктор цепи"?
Вы используете его для вызова одного конструктора из другого конструктора.как можно реализовать "цепочку конструкторов"?
Используйте ключевое слово": 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; } }
Я надеюсь, что следующий пример прольет некоторый свет на цепочку конструкторов.
мой пример использования здесь, например, вы ожидаете, что пользователь передаст каталог в ваш конструктор, пользователь не знает, какой каталог передать и решает позволить назначить папку по умолчанию. вы поднимаетесь и назначаете каталог по умолчанию, который вы думаете будет работать.
Кстати, я использовал LINQPad для этого примера, если вам интересно, что *.Дамп() есть.
ура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; } }
есть еще один важный момент в цепочке конструктора: порядок. Зачем? Предположим, что у вас есть объект, создаваемый во время выполнения платформой, которая ожидает, что это конструктор по умолчанию. Если вы хотите иметь возможность передавать значения, все еще имея возможность передавать в конструкторе аргументов, когда вы хотите, это чрезвычайно полезно.
Я мог бы, например, иметь резервную переменную, которая получает значение по умолчанию моим конструктором по умолчанию, но имеет возможность быть перезаписанный.
public class MyClass { private IDependency _myDependency; MyClass(){ _myDependency = new DefaultDependency(); } MYClass(IMyDependency dependency) : this() { _myDependency = dependency; //now our dependency object replaces the defaultDependency } }
Comments