Доброго времени суток, столкнулся с такой проблемой. Есть абстрактный класс ViewModel, который содержит логику добавления данных в коллекцию для отображения в GUI.
public abstract class ViewModel {
public ObservableCollection
protected void selectData(string query) {
// ...
// Логика получения reader
// ...
IModel item = this.createObject(reader);
this.Data.Add(item);
}
}
Также есть классы моделек, все они реализую интерфейс IModel, код приводить не буду, в нем нет необходимости. Класс реализующий ViewModel выглядит так:
public class UsersViewModel : ViewModel {
public UsersViewModel() {
string query = "SELECT TOP 300 * FROM users ORDER BY reputation DESC";
this.selectData(query);
}
protected override IModel createObject(SqlDataReader reader) {
return new User(reader);
}
}
Проблема собственно в методе createObject. Во всех подклассах он делает одну единственную вещь: возвращает экземпляр класса модели. Мне бы хотелось от него избавится. И сделать так, что бы в абстрактном классе ViewModel метод selectData сам создавал тот объект модели, какой нужно, а какой именно, он бы узнавал из подкласса. Метод должен выглядеть примерно так:
protected void selectData(string query) {
// Логика получения reader
IModel item = new Тип_Модели_из_подкласса(reader);
this.Data.Add(item);
}
Кажется мне, что проблему можно решить с помощью обобщений, но не знаю как. Или создать в подклассе свойство, которое будет уточнять какую именно реализацию интерфейса IModel нужно использовать. Как мне это реализовать? Заранее спасибо.
Ответ
Ну например, один из методов такой:
public abstract class ViewModelImpl
Ну и наследуйте конкретные классы от ViewModelImpl
(Если бы конструктор T был без параметров, можно было бы обойтись без рефлексии.)
Для лучшей читаемости можно вынести метод:
private T CreateModelItem(SqlDataReader reader)
{
return (T)Activator.CreateInstance(typeof(T), reader);
}
protected void selectData(string query)
{
// Логика получения reader
IModel item = CreateModelItem(reader);
this.Data.Add(item);
}
Впрочем, у вас этот вспомогательный метод уже есть, он называется createObject
Комментариев нет:
Отправить комментарий