С Новым годом! Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.87/15: Рейтинг темы: голосов - 15, средняя оценка - 4.87
4 / 0 / 0
Регистрация: 12.01.2015
Сообщений: 51
1

Реализация шаблонного метода интерфейса

12.01.2015, 08:50. Показов 3037. Ответов 18
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Суть в том, что есть интерфейс
C#
1
2
3
4
5
 
interface IAction
    {
        List<T> GetAll<T>();
    }
и множество классов реализующих его, по типу
C#
1
2
3
4
5
6
7
 
    public class MyClass1 : IAction
    {
        public List<SomeClass1> GetAll<SomeClass1>()
        {
            return SomeClass1List;//тут лист обьектов пользовательского класса
        }
SomeClass1 - пользовательский класс, их много(12 штук).
ругается что не может преобразовать SomeClass1List к List<SomeClass1>.
Предугадывая вопрос зачем такой гемор - задания куратора.
Вопрос заключается в том, можно ли реализовать интерфейс, с четким указание что возращать в момент реализации в пользовательском классе?
0
Лучшие ответы (1)
Programming
Эксперт
9485 / 562 / 19
Регистрация: 12.04.2006
Сообщений: 11,671
Блог
12.01.2015, 08:50
Ответы с готовыми решениями:

Реализация шаблонного интерфейса
public interface IPresenter { IView View { get; set; } IModel Model { get; set; } }...

Реализация метода интерфейса
Всем доброго времени суток. При попытке запуска выдает ошибку что не реализован метод getLen. я...

Почему не компилируется реализация обобщенного метода интерфейса?
Здравствуйте у меня есть интерфейс IRecord и никак не могу реализовать её в классе AccountRecord...

Различная реализация метода при наследовании интерфейса
Создаю класс который наследую от интерфейса. В классе есть private массив с параметрами и допустим...

18
2152 / 1289 / 516
Регистрация: 04.03.2014
Сообщений: 4,092
12.01.2015, 10:07 2
Цитата Сообщение от Segat Посмотреть сообщение
Вопрос заключается в том, можно ли реализовать интерфейс, с четким указание что возращать в момент реализации в пользовательском классе?
не понятен вопрос, можно реализовать лишь то что указано в контракте (интерфейсе)
то есть как сигнатура указана в интерфейсе. точна такая должна быть и в реализуемом методе

Цитата Сообщение от Segat Посмотреть сообщение
ругается что не может преобразовать SomeClass1List к List<SomeClass1>.
показывайте что такое SomeClass1List
0
4 / 0 / 0
Регистрация: 12.01.2015
Сообщений: 51
12.01.2015, 10:25  [ТС] 3
Цитата Сообщение от Metall_Version Посмотреть сообщение
не понятен вопрос, можно реализовать лишь то что указано в контракте (интерфейсе)
то есть как сигнатура указана в интерфейсе. точна такая должна быть и в реализуемом методе


показывайте что такое SomeClass1List
SomeClass1List - лист сущностей EntityFramework. То есть Сущность.ToList();
не понятен вопрос, можно реализовать лишь то что указано в контракте (интерфейсе)
то есть как сигнатура указана в интерфейсе. точна такая должна быть и в реализуемом методе
Суть была в том чтобы при работе с вин формой была функция
C#
1
2
3
4
MyFunc(IAction SomeInterface)// необязательно интерфейс, это мну счас пытается сделать так
{
 что-то_по_логике=SomeInterface.GetAll();
}
Поэтому хотел дать каждому классу работы с сущностью(таки опять задание,ВСЯ логика в своих классах), родителя интерфейс, с шаблонным методом GetAll, а в классе жестко приводить тип Т метода, к типу возвращаемому. С полностью шаблонным интерфейсом такое у меня получилось, но там надо указывать тип при создании объекта интерфейса, поэтому попытался сделать отдельно шаблонный метод, обломался и написал сюда.
C#
1
2
3
4
5
 
     public List<сущность> GetAll<сущность>()
        {
            return db.сущность.ToList();
        }
0
2152 / 1289 / 516
Регистрация: 04.03.2014
Сообщений: 4,092
12.01.2015, 10:33 4
Segat, вы пытаетесь сделать репозиторий?
тогда это все по другому делается

Цитата Сообщение от Segat Посмотреть сообщение
SomeClass1List - лист сущностей EntityFramework. То есть Сущность.ToList();
как сущностей , что за класс?
0
4 / 0 / 0
Регистрация: 12.01.2015
Сообщений: 51
12.01.2015, 10:36  [ТС] 5
Дайте плиз ссылку на репозиторий, про класс, в нем вся работа с сущностями(все поверки, добавление/изменение/удаление, выборки необходимые для моей программы и т.д.)
0
2152 / 1289 / 516
Регистрация: 04.03.2014
Сообщений: 4,092
12.01.2015, 10:41 6
вот дженерик репа
http://www.codeproject.com/Tip... -Dependenc
0
4 / 0 / 0
Регистрация: 12.01.2015
Сообщений: 51
13.01.2015, 08:27  [ТС] 7
Репозиторий всё-таки немного не то, что я хотел. т.к.
C#
1
2
3
4
IRepository<сущность> rep = new CustomersRepository();
foreach(var element in rep.GetAll())
 
{...}
Сущность нужно будет указывать серавно как я понял, при каждой работе с репозиторием.
То есть при вынесению в отдельную функцию
C#
1
2
3
4
5
void SomeFunc(IRepository<сущность> rep)
{
foreach(var element in rep.GetAll())
}
{...}
будет требоваться явное указание с чем мы работаем. А я хотел использовать принцип наследования -> указателю на родителя, можно задать любой объект наследник.

Добавлено через 20 часов 56 минут
Если кто-то сюда заглянет ещё: репозиторий для каждой таблицы у меня есть, то что я просил тут должно было стать просто помощью разработчику интерфейса вин формы. В целом для этого же начинал тему про SQL, для уменьшения работы на вин форме. А писать общий репозиторий чего-то не хочется.
0
2152 / 1289 / 516
Регистрация: 04.03.2014
Сообщений: 4,092
13.01.2015, 11:36 8
Лучший ответ Сообщение было отмечено Metall_Version как решение

Решение

Segat, нет я имел ввиду как раз репу дженерик, где каждый метод работы с хранинилещем описывается один раз, не нужно для каждой сущности его писать..
вот нашел в закромах старенькую репу,
Кликните здесь для просмотра всего текста
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
public class Repository<TEntity> : IRepository<TEntity> where TEntity : BaseEntity
    {
        private readonly DbContext _context;        //контекст, предоставляет доступ к базе данных
        private readonly DbSet<TEntity> _dbSet;     //представляет таблицу из базы - одну определенную сущность
 
        /// <summary>
        /// Создание хранилища
        /// </summary>
        public Repository(DbContext dbContext)
        {
            _context = dbContext;
            _dbSet = _context.Set<TEntity>();
        }
 
        #region IRepository
 
        /// <summary>
        /// Сохранение новой записи в хранилище(если id = 0), или обновление уже существующей
        /// </summary>
        /// <param name="entity">Сущность которую нужно внести в базу, или обновить</param>
        public TEntity SaveOrUpdate(TEntity entity)
        {
            if (entity.Id == 0) return _dbSet.Add(entity);
 
            _dbSet.Attach(entity);
            _context.Entry(entity).State = EntityState.Modified;
 
            return entity;
        }
 
        /// <summary>
        /// Удалить сущность из хранилища
        /// </summary>
        public void Remove(TEntity entity)
        {
            _dbSet.Remove(entity);
        }
 
        /// <summary>
        /// Удалить список сущностей из хранилища
        /// </summary>
        public void RemoveRange(IEnumerable<TEntity> entity)
        {
            _dbSet.RemoveRange(entity);
        }
 
        /// <summary>
        /// Получить сущность по id
        /// </summary>
        public TEntity Get(int id)
        {
            return _dbSet.FirstOrDefault(v => v.Id == id);
        }
 
        /// <summary>
        /// Найти одну сущность по заданому предикату
        /// </summary>
        /// <param name="predicate">Предикат поиска</param>
        public TEntity FindOne(Expression<Func<TEntity, bool>> predicate)
        {
            return _dbSet.SingleOrDefault(predicate);
        }
 
        /// <summary>
        /// Найти все сущности по заданому предикату
        /// </summary>
        /// <param name="predicate">Предикат поиска</param>
        public IQueryable<TEntity> FindAll(Expression<Func<TEntity, bool>> predicate)
        {
            return _dbSet.Where(predicate);
        }
 
        /// <summary>
        /// Получить все сущности данного типа из хранилища
        /// </summary>
        public IQueryable<TEntity> All()
        {
            return _dbSet;
        }
 
        /// <summary>
        /// Сохранить изменения в хранилище
        /// </summary>
        public void SaveChanges()
        {
            try
            {
                _context.SaveChanges();
            }
            catch (DbEntityValidationException dbValidEx) //отлавливаем ошибки валидации в базе
            {
                throw new DataException(dbValidEx.Message, dbValidEx);
            }
            catch (DataException dataEx)                    //отлавливаем ошибки из базы
            {
                throw new DataException(dataEx.Message, dataEx);
            }
            catch (Exception ex)                            //отлавливаем остальные ошибки
            {
                throw new Exception(ex.Message, ex);
            }
        }
        #endregion
 
        /// <summary>
        /// Освобождение всех ресурсов
        /// </summary>
        public void Dispose()
        {
            _context.Dispose();
        }
    }


как видно ограничение стоит по базовой сущности, репа писалась для EF codefirst, базовая сущность там класс с одним полем ID (грубо говоря), от этого класса все остальные наследуются

а вот сам интерфейс
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 /// <summary>
    /// Определяет методы для универсального хранилища данных, типа TEntity
    /// </summary>
    /// <typeparam name="TEntity">Тип сущности хранилища</typeparam>
    public interface IRepository<TEntity> : IDisposable where TEntity : class 
    {
        TEntity SaveOrUpdate(TEntity entity);
 
        void Remove(TEntity entity);
 
        void RemoveRange(IEnumerable<TEntity> entity);
 
        TEntity FindOne(Expression<Func<TEntity, bool>> predicate);
 
        TEntity Get(int id);
 
        IQueryable<TEntity> FindAll(Expression<Func<TEntity, bool>> predicate);
 
        IQueryable<TEntity> All();
 
        void SaveChanges();
    }


Добавлено через 6 минут
а пользоваться ей вот так
C#
1
2
3
4
            using (var repa = new Repository<SomeClass1>(context))
            {
                repa.SaveOrUpdate(new SomeClass1());
            }
Добавлено через 53 секунды
где context это контекст от EF, производный от DbContext
1
4 / 0 / 0
Регистрация: 12.01.2015
Сообщений: 51
14.01.2015, 11:38  [ТС] 9
тут using (var repa = new Repository<SomeClass1>(context)) есть, а я хотел попытаться пройти через, если я правильно помню название, позднее связывание, т.е. выбирая наследника в процессе работы программы, используя ссылку на родителя. Интерфейсом шаблонным, али родителем это делать мне без разницы. К слову я EF брал кальку с существующей бд, разве он не создаёт аналог репозитория?

Добавлено через 3 часа 25 минут
Кароче, пока буду говорить с куратором о переходе на чистий sql. Буду использовать DataTable+ наследование. Спс всем кто отписыавлся тут!

Добавлено через 32 секунды
Хотя если кто-то поймет о чем я, и отпишет буду искренне рад.
0
2152 / 1289 / 516
Регистрация: 04.03.2014
Сообщений: 4,092
14.01.2015, 12:44 10
Цитата Сообщение от Segat Посмотреть сообщение
а я хотел попытаться пройти через, если я правильно помню название, позднее связывание, т.е. выбирая наследника в процессе работы программы, используя ссылку на родителя.
эм не понимаю, как во время работы вы хотите выбрать наследника, и зачем...
0
286 / 192 / 56
Регистрация: 25.12.2012
Сообщений: 640
15.01.2015, 11:57 11
Может так
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
interface IAction
{
    List<T> GetAll<T>();
}
class A : IAction
{            
    public List<T> GetAll<T>()
    {
        var e = Enumerable.Range(0, 1);
        //return e.ToList();//error
        return e.ToList() as List<T>;
    }
}
0
4 / 0 / 0
Регистрация: 12.01.2015
Сообщений: 51
16.01.2015, 11:44  [ТС] 12
эм не понимаю, как во время работы вы хотите выбрать наследника, и зачем...
Идея была в том,чтобы очень сильно облегчить себе работу с вин формой). С чистым SQL подобное делается минут за 5,а вот с ORM я не представляю как это сделать(

Добавлено через 17 часов 50 минут
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
interface IAction
{
    List<T> GetAll<T>();
}
class A : IAction
{            
    public List<T> GetAll<T>()
    {
        var e = Enumerable.Range(0, 1);
        //return e.ToList();//error
        return e.ToList() as List<T>;
    }
}
Как использовать, если я получаю тип через метод(как System.type)?

Добавлено через 2 часа 34 минуты
Кароче теперь только 1 вопрос, я вызываю шаблонный метод внутри функции можно ли ему передать тип как параметр?
C#
1
2
3
4
void func(Type SomeType)
{
Some.GetEAll<SomeType>();
}
Пишет что незнает что такое SomeType
void func()
{
Some.GetEAll<Some.Somemetod()>();//Метод возвращает тип
}
[/CSHARP]
тут ругается на выделенные скобочки.
0
2152 / 1289 / 516
Регистрация: 04.03.2014
Сообщений: 4,092
16.01.2015, 14:13 13
Цитата Сообщение от Segat Посмотреть сообщение
передать тип как параметр?
для этого я привел пример с обобщенным классом, его так и юзают, например метод получения всех сущностей
C#
1
2
3
4
5
List<someclass> list;
using (var repa = new Repository<someclass>(context))
{
      list = repa.All().ToList();
}
если пугают юзинги (открытие и диспозинг контекста) то можно так написать
C#
1
2
3
var repa = new Repository<someclass>(context))
var list = repa.All().ToList();
repa.Dispose();
сам Dispose можно прописывать и в классе репы в каждом методе, но тогда для каждого метода придется заново репу создавать. поэтому удобно - открыл юзинг. поработал с репой, закрыл.

а вообще в более менее серьезных проектах, к репе нужно писать уровень bll, в которой инкапсулировать всю работу с репой.
0
4 / 0 / 0
Регистрация: 12.01.2015
Сообщений: 51
16.01.2015, 19:41  [ТС] 14
Цитата Сообщение от Metall_Version Посмотреть сообщение
для этого я привел пример с обобщенным классом, его так и юзают, например метод получения всех сущностей
C#
1
2
3
4
5
List<someclass> list;
using (var repa = new Repository<someclass>(context))
{
      list = repa.All().ToList();
}
если пугают юзинги (открытие и диспозинг контекста) то можно так написать
C#
1
2
3
var repa = new Repository<someclass>(context))
var list = repa.All().ToList();
repa.Dispose();
сам Dispose можно прописывать и в классе репы в каждом методе, но тогда для каждого метода придется заново репу создавать. поэтому удобно - открыл юзинг. поработал с репой, закрыл.

а вообще в более менее серьезных проектах, к репе нужно писать уровень bll, в которой инкапсулировать всю работу с репой.
List<someclass> list;
Вот ЭТО я хочу передать как параметр в функцию, а она воротит нос и пишет что ничего не знает.
0
2152 / 1289 / 516
Регистрация: 04.03.2014
Сообщений: 4,092
16.01.2015, 23:41 15
Цитата Сообщение от Segat Посмотреть сообщение
Вот ЭТО я хочу передать как параметр в функцию, а она воротит нос и пишет что ничего не знает.
в какую функцию, если делать по моему примеру то все работает, только у меня нету методов обобщенных, а только класс...
0
Master of Orion
Эксперт .NET
6100 / 4956 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
17.01.2015, 00:02 16
Segat,
C#
1
2
3
4
void func<SomeType>()
{
Some.GetEAll<SomeType>();
}
0
4 / 0 / 0
Регистрация: 12.01.2015
Сообщений: 51
17.01.2015, 15:18  [ТС] 17
Цитата Сообщение от Psilon Посмотреть сообщение
Segat,
C#
1
2
3
4
void func<SomeType>()
{
Some.GetEAll<SomeType>();
}
SomeType - мне это придется все равно указывать руками где-то, я же хотел просто передавать тип берущийся из, допустим, метода и забивать его как параметр.
C#
1
2
3
4
5
6
7
8
void main()
{
MyFunc(Some.GetType());
}
void MyFunc(Type type)
{
  Some.GetEAll<SomeType>();//как то так, а то откеля брать тип, выбиралось бы при помощи позднего связывания
}
Добавлено через 14 минут
Люди я понимаю, что вы хотите подставлять тип, каждый раз когда идет обращение к сущности(репозиторию), но епт, мне религия непозволяет брать и по 13 АБСОЛЮТНО идентичных действий не выносить в функцию.
0
Master of Orion
Эксперт .NET
6100 / 4956 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
17.01.2015, 19:16 18
C#
1
2
3
4
5
6
7
8
9
10
11
        void main()
        {
            MyFunc(Some.GetType());
        }
        void MyFunc(Type type)
        {
            var sometype = Some.GetType();
            var meth = sometype.GetMethod("GetEAll");
            var genericMethod = meth.MakeGenericMethod(type);
            genericMethod.Invoke(Some, null);
        }
0
4 / 0 / 0
Регистрация: 12.01.2015
Сообщений: 51
18.01.2015, 12:02  [ТС] 19
Цитата Сообщение от Psilon Посмотреть сообщение
C#
1
2
3
4
5
6
7
8
9
10
11
        void main()
        {
            MyFunc(Some.GetType());
        }
        void MyFunc(Type type)
        {
            var sometype = Some.GetType();
            var meth = sometype.GetMethod("GetEAll");
            var genericMethod = meth.MakeGenericMethod(type);
            genericMethod.Invoke(Some, null);
        }
Спасибо... Я правда ажно в ступор впал, как это увидел.
0
18.01.2015, 12:02
cpp_developer
Эксперт
20123 / 5690 / 417
Регистрация: 09.04.2010
Сообщений: 12,546
Блог
18.01.2015, 12:02
Помогаю со студенческими работами здесь

Реализация интерфейса
При помощи интерфейса вычислить корень числа введенного с клавиатуры.

реализация интерфейса
&quot;ConsoleApplication2.Fib&quot; не реализует член интерфейса...

Реализация интерфейса
Написал пример из книги O'Reilly Learning C# 3.0 Chapter 18 создание File-Copier. Все сделал &quot;по...

Реализация интерфейса
Здравствуйте! Имеется один интерфейс и 2 класса наследника. using System; using...


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

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Блоги программистов
Обновление сайта 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
Боты для Телеграм представляют собой автоматизированные программы, которые выполняют различные задачи, взаимодействуя с пользователями через интерфейс мессенджера. В данной статье мы рассмотрим,. . .
Применение компонентов PrimeVue в Vue.js 3 на TypeScript
BasicMan 04.01.2025
Введение в PrimeVue и настройка окружения PrimeVue представляет собой мощную библиотеку компонентов пользовательского интерфейса для Vue. js 3, которая предоставляет разработчикам богатый набор. . .
Как стать Senior developer
cpp_developer 04.01.2025
В современной индустрии разработки программного обеспечения позиция Senior Developer представляет собой не просто следующую ступень карьерной лестницы, а качественно новый уровень профессионального. . .
Что известно о дате выхода Windows 12 и чего от нее ждать
IT_Exp 04.01.2025
В мире технологий постоянно происходят изменения, и операционные системы не являются исключением. Windows 11, выпущенная в октябре 2021 года, принесла множество инноваций и улучшений, но. . .
Что новенького в .NET Core 9
Programming 04.01.2025
Обзор ключевых изменений в . NET Core 9 Платформа . NET Core продолжает активно развиваться, и версия 9 представляет собой значительный шаг вперед в эволюции этой технологии. Новый релиз. . .
Инструкция по установке python3.13.1 в Debian 12
AlexSky-coder 03.01.2025
sudo apt update sudo apt install build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev wget. . .
Затестил триггеры. архив проекта прилагаю с GOA файлами в настройках архиватора проектов.
Hrethgir 03.01.2025
В этот раз нет закольцованности, потому что от неё только глюки, как я понял, логика не вырезанная. Триггеры очень быстрые если верить измерениям с помощью анализатора от Gowin. Есть ещё регистры,. . .
Python в помощь DevOps
IT_Exp 03.01.2025
Причины использования Python в работе DevOps Python стал неотъемлемой частью мира DevOps, и это не случайно. Этот язык программирования обладает множеством преимуществ, которые делают его. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru