Класс инициализаторов C#
У меня есть класс, используемый в нескольких местах в моем коде (Credentials), есть метод, который потребует гораздо больше данных. Я хочу, чтобы все это было в одном классе (ArchiveData), включая исходный (Credentials) класс
Поэтому, когда я создаю класс, я просто хочу назначить все данные из меньшего класса в больший класс. Каков наилучший метод для этого?
Возник подобный вопрос : возможна ли инициализация классов в C#? и было рекомендовано не перезаписывать свойства инициализации. Я не обязательно хочу, я просто хочу метод перегрузки, который добавляет известные значения для меня, чтобы я мог иметь более чистый код, но перегрузка переопределит инициализатор по умолчанию.
Хотя в этом случае у меня всегда будет подкласс, так что удаление исходного инициализатора в этом примере хорошо. Я вижу сценарии, в которых я бы этого не хотел.
Редактировать: Удалена ошибка переполнения стека. Основной вопрос - о лучших методах и преимуществах и недостатках различных способов "есть подкласс".
Код ниже:
Желаемый конечный результат - это чистый способ заставить больший класс иметь все данные меньшего класса:
Credentials credentials = new Credentials("My User Name", "some password");
ArchiveData AD = new ArchiveData(credentials);
Console.Write(AD.credentials.UserID);
Console.Write(AD.credentials.password);
Настройка классов:
public partial class ArchiveData
{
public string DocumentType { get; set; }
public int RTKD { get; set; }
public string RTMSG { get; set; }
public Credentials credentials;
public ArchiveData(Credentials credentials)
{
this.credentials = credentials;
}
}
public class Credentials
{
public string userId { get; set; }
public string password { get; set; }
public Credentials(string userId, string password)
{
this.userId = userId;
this.password = password;
}
}
3 ответа
Наследование должно формировать отношения "есть". Так что вы могли бы иметь Dog : Animal
потому что собака это животное. Это не единственный фактор, который имеет значение при принятии решения о том, должен ли класс наследовать от другого, но это хорошая отправная точка.
В этом случае трудно сказать, правда ли это. Можете ли вы сказать "Архивные данные - это набор учетных данных?" Если так, то ответ iamruss выше - это, вероятно, верный путь. Но, возможно, вы хотите сказать: "Архивные данные имеют набор учетных данных". (Или, что то же самое, "содержит"). В этом случае вы можете сделать что-то вроде этого:
public class ArchiveData
{
public Credentials credentials {get; private set;}
public string userData
{
get
{
return this.userData;
}
set
{
this.userData = value;
}
}
//other properties here
public ArchiveData(Credentials credentials)
{
this.credentials = credentials;
}
}
public class Credentials
{
public string userId { get; set; }
public string password { get; set; }
public Credentials(string userId, string password)
{
this.userId = userId;
this.password = password;
}
}
Теперь, если вы хотите получить идентификатор пользователя и пароль, ваш фрагмент кода будет выглядеть так:
Credentials credentials = new Credentials("My User Name", "some password");
ArchiveData AD = new ArchiveData(credentials);
Console.Write(AD.credentials.UserID);
Console.Write(AD.credentials.password);
Это гораздо более гибкий и легкий подход, чем наследование, поэтому полезно понимать, когда следует выбирать наследование, а когда следует выбирать ограничение и выбирать лучший вариант.
Добро пожаловать в мир ООП!
public class ArchiveData : Credentials
{
public string userData
{
get
{
return this.userData;
}
set
{
this.userData = value;
}
}
//other properties here
public ArchiveData(string userId, string password) : base(userId, password) {}
}
public class Credentials
{
public string userId { get; set; }
public string password { get; set; }
public Credentials(string userId, string password)
{
this.userId = userId;
this.password = password;
}
}
Во-первых, вы не должны расширяться от Credentials, если это не то, что вы действительно хотите (согласно принципу подстановки Лискова). Похоже, что вы хотите сделать что-то вроде этого примера составного объекта демонстрирует:
class Program
{
static void Main(string[] args)
{
var credentials = new Credentials("My User Name", "some password");
var AD = new ArchiveData(credentials);
Console.Write(AD.UserId);
Console.Write(AD.Password);
}
}
public class ArchiveData
{
private readonly Credentials myCredentials;
public string UserData { get; set; }
public string UserId
{
get
{
return this.myCredentials.UserId;
}
}
public string Password
{
get
{
return this.myCredentials.Password;
}
}
public ArchiveData(Credentials credentials)
{
if (credentials == null)
throw new ArgumentNullException();
this.myCredentials = credentials;
}
}
public class Credentials
{
public string UserId { get; set; }
public string Password { get; set; }
public Credentials(string userId, string password)
{
this.UserId = userId;
this.Password = password;
}
}
Одним из преимуществ такого способа (в отличие от взлома LSP) является то, что вы не можете передавать новые экземпляры ArchiveData со старыми экземплярами ArchiveData, поскольку ArchiveData также не является Credentials и, следовательно, не является допустимым параметром. для конструктора.