С Новым годом! Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/8: Рейтинг темы: голосов - 8, средняя оценка - 5.00
33 / 26 / 19
Регистрация: 21.07.2015
Сообщений: 300
1

Интерфейс и обобщения

23.08.2018, 12:23. Показов 1672. Ответов 3
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Коллеги, добрый день.
Решил для себя добить эту тему до более-менее устойчивого понимания. Не легко идет, прошу помочь.
Ниже код тестового приложения, посмотрите плиз кому не лень? Так это все делается, или нужно иначе?

Интерфейс с единственным методом (сбор репозитория)
C#
1
2
3
4
public interface IRepo<T>
{
    List<T> GetRepo<T>();
}
Абстрактный базовый класс (его экземпляры мне не нужны)
C#
1
2
3
4
5
6
7
abstract class BaseClass<T> : IRepo<T>
{
    public int Id { get; set; }
    public string Name { get; set; }
 
    public abstract List<T> GetRepo<T>();
}
Два производных класса. В каждом своя реализация GetRepo()
C#
1
2
3
4
5
6
7
8
class DerivedClassA : BaseClass<DerivedClassA>
{
    public override List<T> GetRepo<T>()
    {
        var repo = DB.ClassARepo();
        return repo as List<T>;
    }
}
C#
1
2
3
4
5
6
7
8
class DerivedClassB : BaseClass<DerivedClassB>
{
    public override List<T> GetRepo<T>()
    {
        var repo = DB.ClassBRepo();
        return repo as List<T>;
    }
}
Сам вызов из Program.cs
C#
1
2
3
4
5
static void Main(string[] args)
{
    var dcARepo = new DerivedClassA().GetRepo<DerivedClassA>();
    var dcBRepo = new DerivedClassB().GetRepo<DerivedClassB>();
}
Все. Заранее спасибо
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
23.08.2018, 12:23
Ответы с готовыми решениями:

Обобщения
Доброго времени суток. Решил немного поковырять С# и застрял на обобщениях. К сути. Имеется класс...

Обобщения
Всем привет, есть строчка кода. Не понимаю, что значит &lt;? super T&gt; тут и зачем это нужно....

Обобщения
program Generics; uses SysUtils; type ///Предоставляет методы Print(), Println(). ...

Обобщения
Всем доброго времени суток! Никак не могу догадаться как работать с обобщенными методами: ...

3
654 / 591 / 171
Регистрация: 17.07.2012
Сообщений: 1,678
Записей в блоге: 1
23.08.2018, 16:35 2
Цитата Сообщение от SPNick Посмотреть сообщение
Интерфейс с единственным методом (сбор репозитория)
У вас репозиторий сам себя "собирает"?

Если DerivedClass1 и DerivedClass2 - доменные типы, то они вообще не должны ничего знать о репозиториях.
Похоже на какую-то извращенную реализацию Active Record паттерна...

И с генериками вы что-то перемутили.
0
33 / 26 / 19
Регистрация: 21.07.2015
Сообщений: 300
23.08.2018, 20:33  [ТС] 3
Cupko, смысл всего этого - спроектировать данные так, чтобы можно было масштабировать приложение без лишнего повторения кода. Чтобы можно было обращаться к GetRepo() любого класса, производного от BaseClass. Как это должно делаться правильно - не знаю. В соседнем топике подсказали вынести в универсальный (обобщенный) интерфейс. Ну вот.. и тыкался весь день и так и сяк

Можно как раньше налепить практически одинаковые методы в каждом из классов и не париться, как до этого делал)) Но после прочтения книжки по проектированию рука не поднимается такое сделать

Цитата Сообщение от Cupko Посмотреть сообщение
Похоже на какую-то извращенную реализацию Active Record паттерна
Это не специально, не знаю о таком
0
.NET senior
441 / 359 / 137
Регистрация: 23.09.2016
Сообщений: 980
24.08.2018, 07:43 4
Лучший ответ Сообщение было отмечено SPNick как решение

Решение

SPNick, Вам же уже объясняли это в предыдущей теме.

BaseClass, DerivedClassA, DerivedClassB - Ваши сущности модели данных, они понятия не должны иметь о том, каким образом и откуда извлекаются данные для заполнения их свойств, и уж точно не должны иметь методов вида GetRepo.

Для корректной реализации желаемого поведения Вам достаточно использовать какой-нибудь Entity Framework или любую другую ORM, которая Вам больше всего нравится / которую Вы лучше знаете.

То есть, в этом случае классы модели данных должны иметь примерно такой вид:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
public abstract class KeyedEntity<TKey> where TKey : struct
{
    public TKey Id { get; set; }
}
 
public class Company : KeyedEntity<Guid>
{
    public string Name { get; set; }
    
    public string Email { get; set; }
    
    public string Phone { get; set; }
}
При построении модели данных на примере Entity Framework (версия 6.2.0) наследник DbContext будет выглядеть примерно так (привожу для примера, в реальном проекте он будет немного посложнее в плане маппинга сущностей на таблицы БД):

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class SuperPuperContext : DbContext
{
    public SuperPuperContext(string nameOrConnectionString) : base(nameOrConnectionString) {}
    
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        var companyBuilder = modelBuilder.Entity<Company>();
        
        companyBuilder.ToTable("Companies");
        companyBuilder.HasKey(x => x.Id, ConfigureCompanyKey);
        companyBuilder.Property(x => x.Id).HasColumnOrder(1);
        companyBuilder.Property(x => x.Name).HasColumnOrder(2).HasMaxLength(64);
        companyBuilder.Property(x => x.Email).HasColumnOrder(3).HasMaxLength(256);
        companyBuilder.Property(x => x.Phone).HasColumnOrder(4).HasMaxLength(64);
        companyBuilder.Property(x => x.CreatedAt).HasColumnOrder(5);
    }
    
    private void ConfigureCompanyKey(PrimaryKeyIndexConfiguration keyConfiguration)
    {
        keyConfiguration.HasName("companies_pk_id");
        keyConfiguration.IsClustered(false);
    }
}
Так как DbContext уже реализует шаблоны Unit of Work и Repository, то накручивание дополнительных слоёв абстракции особой смысловой нагрузки не несёт.

Пример использования:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// данный класс добавлен потому, что с сущностями предметной области лучше не работать напрямую,
// так как Entity Framework проксирует эти классы своими внутренними механизмами
// поэтому лучше явным образом задавать классы-модели, в который будут отображаться данные при выполнении запроса к БД
public class CompanyModel
{
    public Guid Id { get; set; }
    
    public string Name { get; set; }
    
    public string Email { get; set; }
    
    public string Phone { get; set; }
    
    public DateTime CreatedAt { get; set; }
}
 
/* ... */
 
public class CompanyService
{
    private readonly SuperPuperContext _context;
    
    // SuperPuperContext попадает сюда с помощью механизма Dependency Injection
    // CompanyService НЕ ДОЛЖЕН управлять временем жизни контекста EF!
    public CompanyService(SuperPuperContext context) 
    {
        _context = context;
    }
    
    public async Task<List<CompanyModel>> GetCompanies(int pageNumber, int pageSize)
    {
        int skipCount = pageSize * (pageNumber - 1);
        
        var companiesQuery = _context.Set<Company>()
            .OrderByDescending(x => x.CreatedAt)
            .Skip(skipCount)
            .Take(pageSize)
            .Select(x => new CompanyModel
            {
                Id = x.Id,
                Name = x.Name,
                Email = x.Email,
                Phone = x.Phone,
                CreatedAt = x.CreatedAt
            });
            
        var companiesList = await companiesQuery.ToListAsync().ConfigureAwait(false);
        
        return companiesList;
    }
}
1
24.08.2018, 07:43
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
24.08.2018, 07:43
Помогаю со студенческими работами здесь

Обобщения коллекций
Возникла немного тупая проблема, как обобщать коллекции сложно это объяснить, попробую кодом, делал...

Обобщения - can't convert from T to T
что ему надо?) public class Vector&lt;T&gt;{ Vector(){ size=0; array = (T) new Object; }...

Обобщения в интерфейсах
Доброй ночи. Что-то не могу сообразить простенькую задачку, подскажите пожалуйста. Есть несколько...

Вопрос по обобщения
Не могу разобраться почему этот код не рабочий: Gen&lt;Integer&gt; gens = newGen&lt;Integer&gt;; // Неверно!...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Блоги программистов
Как перейти с Options API на Composition API в Vue.js
BasicMan 06.01.2025
Почему переход на Composition API актуален В мире современной веб-разработки фреймворк Vue. js продолжает эволюционировать, предлагая разработчикам все более совершенные инструменты для создания. . .
Архитектура современных процессоров
inter-admin 06.01.2025
Процессор (центральный процессор, ЦП) является основным вычислительным устройством компьютера, которое выполняет обработку данных и управляет работой всех остальных компонентов системы. Архитектура. . .
История создания реляционной модели баз данных, правила Кодда
Programming 06.01.2025
Предпосылки создания реляционной модели В конце 1960-х годов компьютерная индустрия столкнулась с серьезными проблемами в области управления данными. Существовавшие на тот момент модели данных -. . .
Полезные поделки на Arduino, которые можно сделать самому
raxper 06.01.2025
Arduino как платформа для творчества Arduino представляет собой удивительную платформу для технического творчества, которая открывает безграничные возможности для создания уникальных проектов. Эта. . .
Подборка решений задач на Python
IT_Exp 06.01.2025
Целью данной подборки является предоставление возможности ознакомиться с различными задачами и их решениями на Python, что может быть полезно как для начинающих, так и для опытных программистов. . . .
С чего начать программировать микроконтроллер­­ы
raxper 06.01.2025
Введение в мир микроконтроллеров Микроконтроллеры стали неотъемлемой частью современного мира, окружая нас повсюду: от простых бытовых приборов до сложных промышленных систем. Эти маленькие. . .
Из чего собрать игровой компьютер
inter-admin 06.01.2025
Сборка игрового компьютера требует особого внимания к выбору комплектующих и их совместимости. Правильно собранный игровой ПК не только обеспечивает комфортный геймплей в современных играх, но и. . .
Обновление сайта www.historian.b­y
Reglage 05.01.2025
Обещал подвести итоги 2024 года для сайта. Однако начну с того, что изменилось за неделю. Добавил краткий урок по последовательности действий при анализе вредоносных файлов и значительно улучшил урок. . .
Как использовать GraphQL в C# с HotChocolate
Programming 05.01.2025
GraphQL — это современный подход к разработке API, который позволяет клиентам запрашивать только те данные, которые им необходимы. Это делает взаимодействие с API более гибким и эффективным по. . .
Модель полного двоичного сумматора с помощью логических операций (python)
AlexSky-coder 04.01.2025
def binSum(x:list, y:list): s=^y] p=x and y for i in range(1,len(x)): s. append((x^y)^p) p=(x and y)or(p and (x or y)) return s x=list() y=list()
Это мы не проходили, это нам не задавали...(аси­­­­­­­­­­­­­­хро­н­н­ы­й счётчик с управляющим сигналом задержки).
Hrethgir 04.01.2025
Асинхронный счётчик на сумматорах (шестиразрядный по числу диодов на плате, но наверное разрядов будет больше - восемь или шестнадцать, а диоды на старшие), так как триггеры прошли тестирование и. . .
Руководство по созданию бота для Телеграм на Python
IT_Exp 04.01.2025
Боты для Телеграм представляют собой автоматизированные программы, которые выполняют различные задачи, взаимодействуя с пользователями через интерфейс мессенджера. В данной статье мы рассмотрим,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru