powered by simpleCommunicator - 2.0.56     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Хитрая проблема с преобразованием генериков и конкретных типов в C#
6 сообщений из 6, страница 1 из 1
Хитрая проблема с преобразованием генериков и конкретных типов в C#
    #38330477
svnv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Какая-то очень хитрая проблема с генериками и преобразованиями образовалась на ровном месте. Все перепробовал и никак не могу решить.

У меня есть генерический класс с параметром T, который соответственно используется в методах. Один метод принимает массив T[], обрабатывает (например, суммирует), и возвращает результат T. Количество типов T будет ограниченно и скорее всего только примитивы (и строки). Надо сделать это эффективно (скажем, массивы могут быть очень длинными, а обработка очень сложной). Поэтому метод реализует обработку для каждого типа отдельно, но для этого надо генерический входной массив преобразовать в обычный (п.1), а результат из обычного типа в генерический (п.2):

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
    public class Processor<T> {

        public T process(T[] values) {
            if(typeof(T) == typeof(int)) { // Далле T есть int
                int agg = 0;
                int[] array = (int[]) values;   // 1. *** НЕ РАБОТАЕТ ***
                for (int i = 0; i < array.Length; i++) agg += array[i];
                agg /= array.Length;
                return (T) agg;                 // 2. *** НЕ РАБОТАЕТ ***
            }
            if (typeof(T) == typeof(double)) { // Здесь T есть double
                // Быстрая обработка double без генериков
            }
            else {
                throw new NotImplementedException("Пардон.");
            }

        }
    }



Важно, что здесь собственно ничего преобразовывать не надо: мы ведь точно знаем какой типа имеет параметр и далее просто меняет тип переменной. Но компилятор не хочет принимать.

Массив можно преобразовать с помощью (int[])Convert.ChangeType(values, typeof(int[])), но ведь это реальное преобразование, а потому долго. Хочется просто изменить тип переменной, поскольку мы знаем какой типа она имеет.

А с возвратом int'а в виде T вообще не ясно что делать.

Может это просто ограничение C#. Буду благодарен за идеи.
...
Рейтинг: 0 / 0
Хитрая проблема с преобразованием генериков и конкретных типов в C#
    #38330645
petalvik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
svnv,

это ограничение CLR.

Сделай методы
Код: c#
1.
2.
public int process(int[] values)
public double process(double[] values)


и т. д.

Чтобы не писать тонны копипаста, используй кодогенерацию T4. Подключаем к проекту файл Processor.tt, в нём пишем:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".cs" #>

namespace your_namespace
{
    public class Processor
    {
        <#
        foreach(string T in new string[] { "double", "float", "int", "long" }) // добавь нужное
        {
        #>
        public <#=T#> process(<#=T#>[] values) {
            <#=T#> agg = 0;
            for (int i = 0; i < values.Length; i++)
                agg += values[i];
            agg /= values.Length;
            return agg;
        }
        <#}#>
    }
}
...
Рейтинг: 0 / 0
Хитрая проблема с преобразованием генериков и конкретных типов в C#
    #38330676
Фотография Где-то в степи
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
svnv,
Вы пошли путем дженериков.(имхо)
если у вас массивы, так расширьте их методы
~
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
public static object MyExpansion(this IEnumerable col)
         {
             var value1 = col as int[];
             if (value1 != null)
             {
                 var array = value1;
                 var agg = array.Sum();
                 return agg/array.Length;
                
             }
             var value2 = col as string[]; 
             if (value2 != null)
             {
                 return string.Join(string.Empty, value2);
             }
             return null;

         }
...
Рейтинг: 0 / 0
Хитрая проблема с преобразованием генериков и конкретных типов в C#
    #38330683
Фотография Где-то в степи
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Впрочем если не собирать кучи, можно в хелпере компилятор ткнуть мордой - что откуда брать
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
         public static int MyExpansion(this IEnumerable<int> col)
         {
                 var agg = col.Sum();
                 return agg / col.Count();
         }
         public static double MyExpansion(this IEnumerable<double> col)
         {
             var agg = col.Sum();
             return agg / col.Count();
         }
         public static string MyExpansion(this IEnumerable<string> col)
         {
             return string.Join(string.Empty, col);
         }
...
Рейтинг: 0 / 0
Хитрая проблема с преобразованием генериков и конкретных типов в C#
    #38330720
svnv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Где-то в степи,

С расширением массивов это неплохо сделано. Вроде работает. Также для кастинга стало работать 'as' (ошибка была что я просто смену типа делал, а надо 'as'). Спасибо.
...
Рейтинг: 0 / 0
Хитрая проблема с преобразованием генериков и конкретных типов в C#
    #38331099
Фотография buser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
svnv, не зря они generic... даже исходя из названия... :) не стоит их пихать вовсюда, просто по тому, что они есть :)
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Хитрая проблема с преобразованием генериков и конкретных типов в C#
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]