1 / 1 / 0
Регистрация: 22.10.2013
Сообщений: 68
1

Как в обобщенном методе указать ограничения для конструктора?

26.10.2018, 16:47. Показов 559. Ответов 4

Студворк — интернет-сервис помощи студентам
Вот например я хочу создать Класс в котором я буду в основном работать с двумя типами, один из которых наследуется от другого.
И хочу в конструктор наследника передавать экземпляр базового класса.

Такой получился код:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
   public class Test1<T1, T2> 
        where T1 : class , new ()
        where T2 : T1,  new() 
    {
        /// <summary>
        /// Взять список страниц
        /// </summary>
        /// <returns>Возвращает список контекст страниц, в которых заполнено только Id и Title</returns>
        public static List<T2> GetAll()
        {
            using (var uow = new UnitOfWork())
            {
                return uow.GetRepository<T1>().GetAll()
                    .Select(xx => new T2( xx)
                    .ToList();
            }
        }
    }
Но в строчке { .Select(xx => new T2( xx) } есть ошибка. проект не компилируется.

Как в обобщенном методе указать ограничения для конструктора?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
26.10.2018, 16:47
Ответы с готовыми решениями:

Преобразование типов в обобщенном методе
Всем доброго времени суток. public static void Metod&lt;T&gt;(T a1) where T: struct // Какое...

Разные типы в обобщенном методе
Здравствуйте. Хочу написать следующий метод: подается массив типа int или string или object и тд,...

Ограничения типа в обобщённом интерфейсе ICopy<T>
Создал такой интерфейс /// &lt;summary&gt;Интерфейс для создания копии экземпляра того же типа ...

Как указать цвет спрайта в методе Draw
1. Как указать цвет спрайта(в методе Draw) не так: ...(Color.White)а так:...

4
Модератор
Эксперт .NET
15045 / 10271 / 2708
Регистрация: 21.04.2018
Сообщений: 30,454
Записей в блоге: 2
26.10.2018, 16:52 2
Цитата Сообщение от Solomka Посмотреть сообщение
Но в строчке { .Select(xx => new T2( xx) } есть ошибка. проект не компилируется.
Я может чего-то не понял... Но где у Вас конструктор класса T2 принимающий один параметр класса T1 ?
0
Эксперт .NET
1835 / 1343 / 427
Регистрация: 10.06.2011
Сообщений: 2,125
26.10.2018, 16:54 3
C#
1
where T2 : T1,  new()
new() означает, что у типа T2 есть конструктор по-умолчанию, а вы пишете
C#
1
new T2(xx)
Передаёте в T2 аргумент. Компилятор этого не понимает, ему нужен конструктор без аргументов.

Можно сделать так:
C#
1
2
3
4
5
6
7
8
9
public static List<T2> GetAll(Func<T1, T2> create)
{
    using (var uow = new UnitOfWork())
    {
        return uow.GetRepository<T1>().GetAll()
            .Select(xx => create(xx))
            .ToList();
    }
}
C#
1
GetAll<MyType1, MyType2>(x => new MyType2(x))
0
Эксперт .NET
17351 / 12760 / 3340
Регистрация: 17.09.2011
Сообщений: 21,041
26.10.2018, 20:49 4
Цитата Сообщение от Solomka Посмотреть сообщение
Как в обобщенном методе указать ограничения для конструктора?
Никак, вам нужна фабрика, которую и передавайте в метод:
C#
1
2
3
4
5
6
7
8
9
        public static List<T2> GetAll(Func<T1, T2> factory)
        {
            using (var uow = new UnitOfWork())
            {
                return uow.GetRepository<T1>().GetAll()
                    .Select(xx => factory(xx))
                    .ToList();
            }
        }
Использование:
C#
1
List<Apple> apples = Test1<Fruit, Apple>.GetAll(fruit => new Apple(fruit));
0
TheGreatCornholio
1250 / 728 / 285
Регистрация: 30.07.2015
Сообщений: 2,407
26.10.2018, 21:53 5
Цитата Сообщение от Solomka Посмотреть сообщение
Как в обобщенном методе указать ограничения для конструктора?
Никак, но объект можно создать следующим образом
C#
1
2
3
4
5
6
            using (var uow = new UnitOfWork())
            {
                return uow.GetRepository<T1>().GetAll()
                                .Select(xx => (T2)Activator.CreateInstance(typeof(T2), xx))
                                .ToList();
            }
Добавлено через 42 минуты
Еще есть один вариант, но без наследования Т2 от Т1:

Кликните здесь для просмотра всего текста
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
using System;
using System.Collections.Generic;
using System.Linq;
 
namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Test1<Fruit, Apple>.GetAll();
            //Test1<Fruit, Cabbage>.GetAll(); //compilation fails
        }
    }
 
    class Test1<T1, T2> where T1 : Fruit, new()
                        where T2 : MustHaveConstructor<T1>
    {
        public static List<T2> GetAll()
        {
            return new T1[] { }.Select(t1 => (T2)Activator.CreateInstance(typeof(T2), t1)).ToList();
        }
    }
 
    class Fruit
    {
 
    }
 
    class Apple : MustHaveConstructor<Fruit>
    {
        public Apple(Fruit fruit) : base(fruit)
        { }
    }
 
    class Cabbage
    {
 
    }
 
    abstract class MustHaveConstructor<T>
    {
        public MustHaveConstructor(T param)
        { }
    }
}


Очевидно, что было бы неплохо унаследоваться от 2 классов, но C# не поддерживает множественное наследование.
Однако классы можно связать интерфейсом, например
C#
1
where MustHaveConstructor<T1>, IFruit
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
26.10.2018, 21:53
Помогаю со студенческими работами здесь

Как указать ограничения на тип данных что бы выполнялось условие ИЛИ
Подскажите как указать ограничения на тип данных что бы выполнялось условие ИЛИ. Например метод: ...

Нужно чтобы введённый студент в методе in вывелся на экран как в методе out
#include&lt;conio.h&gt; #include&lt;stdio.h&gt; #include&lt;iostream.h&gt; #include&lt;windows.h&gt;...

Почему при вызове конструктора из конструктора нельзя передавать this как аргумент?
Есть такой код: public class Order { { } Order(){ ...

В чём отличия конструктора копирования и конструктора перемещения? Где и как их нужно использовать?
Помогите разобраться в копирующем и перемещающем конструкторах. В чём их существенное отличие и...


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

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru