Короткий ответ
У вас есть вопрос о том, как читать ваш файл?
private bool ManagerExists(int managerId)
{
return this.ReadManagers().Where(manager => manager.Id == managerId).Any();
}
private IEnumerable<Manager> ReadManagers()
{
using (var reader = System.IO.File.OpenText(managersFileName))
{
while (!reader.EndOfStream)
{
string lineManagerName = reader.ReadLine();
string lineMangerId = reader.ReadLine();
string managerName = ExtractValue(lineManagerName);
int managerId = Int32.Parse(ExtractValue(lineManagerId));
yield return new Manager
{
Id = managerId,
Name = managerName,
}
}
}
private string ExtractValue(string text)
{
// the value of the read text starts after the space:
const char separator = ' ';
int indexSeparator = text.IndexOf(separator);
return text.SubString(indexSeparator + 1);
}
Длинный ответ
Я вижу несколько проблем в вашем дизайне.
Самое главное, что вы переплетаете работу вашего менеджера с вашей формой. Вы должны разделить свои проблемы .
Очевидно, у вас есть понятие последовательности менеджеров, у каждого менеджера есть имя (имя, фамилия) и идентификатор менеджера, а в будущем возможно другое properties.
Эта последовательность постоянна: она где-то сохраняется, и если вы загрузите ее снова, у вас будет та же последовательность менеджеров.
В этой версии вы хотите видеть, если Менеджер с данным ManagerId существует. Может быть, в будущем вам может понадобиться больше функций, например, получение информации о диспетчере с определенным идентификатором, или получение всех диспетчеров, или go сумасшедший: добавление / удаление / изменение диспетчеров!
Вы видите в этом описании Я вообще не упомянул твои формы. Поскольку я отделил его от ваших форм, вы можете использовать его в других формах или даже в классе, который не имеет ничего общего с формой, например, вы можете использовать его в модульном тесте.
Я описал, что Мне нужен был такой генерал из, что в будущем, возможно, даже поменяю его. Пользователи моей коллекции постоянных менеджеров даже не заметят этого: я могу поместить его в файл JSON или XML; Я могу сохранить данные в словаре, базе данных или, возможно, даже получить их из inte rnet.
Все, что нужно знать пользователям, это то, что они должны создать экземпляр класса, используя некоторые параметры, и bin go, вы можете получить менеджеров.
Вы также даете пользователям свобода решать, как данные должны быть сохранены: если они хотят сохранить их в файле JSON, изменения в вашем классе формы будут минимальными.
Объект, который хранит последовательности объектов, довольно часто называется репозиторием.
Давайте создадим несколько классов:
interface IManager
{
public int Id {get;}
public string Name {get; set;}
}
interface IManagerRepository
{
bool ManagerExists(int managerId);
// possible future extensions: Add / Retrieve / Update / Delete (CRUD)
IManager Add(IManager manager);
IManager Find(int managerId);
void Update(IManager manager);
void Delete(int ManagerId);
}
class Manager : IManager
{
public Id {get; set;}
public string Name {get; set;}
}
class ManagerFileRepository : IManagerRepository,
{
public ManagerFileRepository(string fileName)
{
// TODO implement
}
// TODO: implement.
}
ManagerFileRepository сохраняет менеджеров в файл. Он скрывает от внешнего мира внутреннюю структуру файла. Это может быть ваш формат файла, это может быть CSV-файл или JSON / XML.
Я также разделил интерфейс, поэтому, если вы позже решите сохранить данные в другом месте, например в Словаре (для модульных тестов) или в базе данных пользователи вашего класса Repository не увидят разницы.
Давайте сначала посмотрим, можете ли вы использовать этот класс.
class MyForm : Form
{
const string managerFileName = ...
private IManagerRepository ManagerRepository {get;}
public MyForm()
{
InitializeComponent();
this.ManagerRepository = new ManagerFileRepository(managerFileName);
}
public bool ManagerExists(int managerId)
{
return this.ManagerRepository.ManagerExists(managerId);
}
Теперь давайте обработаем ваш keyPress:
private void Employee_Id_TextBox_KeyPress(object sender, KeyPressEventArgs e)
{
TextBox textBox = (TextBox)sender;
... // code about numbers and enter key
int enteredManagerId = Int32.Parse(textBox.Text);
bool managerExists = this.ManagerExists(enteredManagerId);
if (managerExists) { ... }
}
Этот код, кажется, делает то, что вы хотите, простым способом. Выглядит прозрачным. ManagerRepository можно тестировать, использовать повторно, его легко расширить или изменить, потому что пользователи этого не заметят. Так что класс выглядит хорошо. Давайте реализуем
Implement ManagerFileRepository
Есть несколько способов реализовать чтение файла:
(1) Прочитать все во время построения
и сохранить прочитанные данные в памяти . Если вы добавите менеджеров, они не сохранятся, пока вы этого не скажете. Преимущества: быстро после первого запуска. Вы можете внести изменения, а затем решить все равно не сохранять их, так что это похоже на редактирование любого другого файла. Недостаток: если ваша программа выйдет из строя, вы потеряете свои изменения.
(2) Читайте файл каждый раз, когда вам нужна информация
Преимущество: данные всегда актуальны, даже если другие редактировали файл пока работает ваша программа. Если вы измените коллекцию менеджера, она будет немедленно сохранена, чтобы ее могли использовать другие.
Выбор решения зависит от размера файла и важности того, чтобы данные никогда не терялись. Если ваш файл содержит миллионы записей, возможно, было не очень разумно сохранять данные в файле. Рассмотрите возможность сохранения SQLite в небольшой, довольно быстрой базе данных.
class ManagerFileRepository : IManagerRepository, IEnumerable<IManager>
{
private readonly IDictionary<int, IManager> managers;
public ManagerFileRepository(string FileName)
{
this.managers = ReadManagers(fileName);
}
public bool ManagerExists(int managerId)
{
return this.Managers.HasKey(managerId);
}
private static IEnumerable<IManager> ReadManagers(string fileName)
{
// See the short answer above
}
}
Возможности для улучшения
Если вы будете использовать репозиторий менеджера для других целей, подумайте о том, чтобы позволить репозиторию реализовать ICollection<IManager>
и IReadOnlyCollection<IManager>
. Это довольно просто:
public IEnumerable<IManager> GetEnumerator()
{
return this.managers.Values.GetEnumerator();
}
public void Add(IManager manager)
{
this.managers.Add(manager.Id, manager);
}
// etc.
Если вы добавляете функции для изменения коллекции менеджеров, вам также понадобится метод сохранения:
public void Save()
{
using (var writer = File.CreateText(FullFileName))
{
const string namePrefix = "ManagerName: ";
const string idPrefix = "ManagerLoginId: ";
foreach (var manager in managers.Values)
{
string managerLine = namePrefix + manager.Name;
writer.WriteLine(managerLine);
string idLine = idPrefix + manager.Id.ToString();
writer.WriteLine(idLine);
}
}
}
Другой метод улучшения: ваша файловая структура . Рассмотрите возможность использования более стандартной файловой структуры: CSV, JSON, XML. Существует множество пакетов NUGET (CSVHelper, NewtonSoft. Json), которые делают чтение и запись менеджеров намного более надежными. вы можете повторно использовать репозиторий менеджеров, особенно если вам нужна функциональность для добавления / извлечения / обновления / удаления менеджеров.
Из-за разделения намного проще проводить модульное тестирование ваших функций. И будущие изменения не будут мешать пользователям репозитория, потому что они не заметят, что данные изменились.