#c# #console-application
#c# #консольное приложение
Вопрос:
На данный момент установщик работает, однако он не информирует пользователя сразу после ввода неверных данных. После создания пользователя он будет сохранен в файле Json. Здесь отображается ошибка, а это не то, что я хочу. Я думал о том, чтобы создать исключение в установщике, а затем добавить еще один catch в процедуру AddPatient? Мне немного любопытно, будет ли это хорошо / плохо.
}
private string gender;
public string UserGender
{
get
{
return gender;
}
set
{
if (value != "m" || value != "f")
{
Console.Write("Error: Please enter m or f: ");
}
}
Комментарии:
1. Ваша процедура не вызывает свойство PatientGender. Было бы намного лучше для удобства чтения, если бы вы могли предоставить немного больше фрагментов кода вашего класса.
2. извиняюсь, я вставил больше кода из класса Patient это более полезно?
Ответ №1:
Свойства в C # отвечают в основном за инкапсуляцию данных, и это хороший подход, чтобы сделать их как можно более простыми. Пожалуйста, прочитайте о принципе единой ответственности.
Что я предлагаю, на случай, если вы хотите добавить какое-либо правило проверки в свое свойство PatientGender, так это позволить свойству отвечать только за правильность вашего ввода и не помещать туда часть логики чтения данных. Вот простой пример того, как вы можете это сделать, просто изменив свой код:
public string PatientGender
{
get { return gender; }
set
{
if (value == "male" || value == "female")
{
gender = value;
}
else
{
// As it was noted in the comment, we should notify the caller that the validation has failed
Console.WriteLine("Incorrect input");
// or throw an exception here
}
}
}
В вашем классе Patient вы можете добавить процедуру, которая будет считывать вводимые пользователем данные и проверять вводимое значение до тех пор, пока оно не станет правильным:
public Patient ReadAndValidatePatientGender(Patient patient)
{
while (true)
{
var input = Console.ReadLine();
if (input.Equals("male", StringComparison.OrdinalIgnoreCase) || input.Equals("female", StringComparison.OrdinalIgnoreCase))
{
patient.PatientGender = input;
return patient;
}
}
}
Затем в вашей основной процедуре, где вы создаете объект класса Patient, вы вызовете процедуру ReadAndValidatePatientGender:
currentPatinet = ReadAndValidatePatientGender(currentPatient);
Комментарии:
1. Выборочный выбор установки значения только в том случае, если оно действительно, не является хорошим подходом, ИМХО. Вызывающий абонент никогда не узнает, что его действие не было замечено, если они явно не вызовут получатель впоследствии.
2. @Xerillio Да, полностью согласен с вашей заметкой. Означает ли это, что в случае добавления некоторой проверки в установщик, когда проверка фактически завершается неудачей, мы всегда должны уведомлять об этом?
3. @Xerillio Я обновил свой ответ с учетом вашего комментария, большое спасибо.
4. @OmelianLevkovych: использование консольного ввода-вывода в качестве уведомления о недопустимом значении не является хорошим подходом, imo. Вы должны выдать исключение, которое может быть перехвачено и обработано везде, где это имеет смысл (например, в пользовательском интерфейсе).
5. @Xerillio Спасибо, определенно выглядит намного лучше. Иногда достаточно сложно ответить на простой вопрос, не добавляя слишком много сложностей для человека, который создал вопрос. Однако я полностью согласен с тем, что мой ответ слишком далек от идеала, и я должен был сделать это правильно с самого начала. Еще раз спасибо 🙂
Ответ №2:
Если вы ищете хороший дизайн своего класса / свойств, вам следует подумать о том, чтобы сделать его максимально простым для понимания и использования с точки зрения «вызывающих». Это означает, что если у вас есть какие-то особые требования к тому, какой ввод должно разрешать свойство, попробуйте использовать тип, который гарантирует, что вызывающий объект не сможет использовать свойство неправильно.
Я не знаю, насколько вы новичок в C #, поэтому вы можете захотеть разобраться, что такое an enum
. В этом случае я бы ввел перечисление Gender
:
public enum Gender
{
Male,
Female,
Other
}
Затем ваше свойство должно иметь Gender
в качестве своего типа:
private Gender gender;
public Gender PatientGender
{
get
{
return gender;
}
set
{
this.gender = value;
}
}
Теперь легко понять все возможные значения, которые допускает свойство. Если вы хотите иметь возможность преобразовать строку в это перечисление, вы можете добавить вспомогательный метод:
public static Gender ConvertToGender(string genderString)
{
var genderLowercase = genderString.ToLower();
switch (genderLowercase)
{
case "male":
return Gender.Male;
case "female":
return Gender.Female;
default:
return Gender.Other;
}
}
(в качестве альтернативы генерируется исключение вместо возврата Gender.Other
)