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

Преобразование типов в обобщенном методе

28.06.2010, 14:22. Показов 19281. Ответов 22
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем доброго времени суток.

C#
1
2
3
4
5
6
7
8
9
public static void Metod<T>(T[] a1) where T: struct  // Какое поставить ограничение, чтобы можно было вводить только числовые данные, и исключить строки, символы и т.п.? 
{
T j = 123; // Неявное преобразование типа 'int' в 'T' невозможно
for(int i = 0; i < a1.Lenght; i++) 
                {
                    a1[i] = j;
                    j += 123; // Неявное преобразование типа 'int' в 'T' невозможно; Оператор "+=" не может применяться к операндам типа "T" и "int"
                }
}
Собственно, вылетает несколько ошибок преобразования типов, и не уверен, какие поставить ограничения. Конструкция вида
C#
1
where T: (short||byte||int)
не работает.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
28.06.2010, 14:22
Ответы с готовыми решениями:

Преобразование типов
Подскажите, пожалуйста! Я не сильна в C#. Я ввожу в textBox любое отрицательное число....

Преобразование типов данных
Есть допустим 3 неких объекта (их может быть и тысячи), у них есть параметр &quot; дата &quot; (число когда...

Преобразование типов - большая нагрузка на ЦП
Здравствуйте. Пишу downloader, так сказать, менеджер закачки. Вычисляю while ((int)(readCount...

Возможно ли создать своё преобразование типов
Есть какая-то структура: struct MyStruct { public int value; public string...

22
87 / 87 / 26
Регистрация: 04.01.2010
Сообщений: 270
28.06.2010, 16:10 2
Цитата Сообщение от MagiicKing Посмотреть сообщение
where T: (short||byte||int)
так нельзя

возможно вот так:

C#
1
2
3
4
5
        public static void Method<T>(T item)
        {
            if (item.GetType().BaseType is int)
            { }
        }
0
3 / 3 / 0
Регистрация: 31.01.2010
Сообщений: 36
28.06.2010, 17:55  [ТС] 3
Все равно выдает, что неявное преобразование невозможно. А явное преобразование сделать тоже не получается:
C#
1
2
3
T a;
int b = 0;
a = (T)b; // Преобразование типа "int" в "T" невозможно
0
87 / 87 / 26
Регистрация: 04.01.2010
Сообщений: 270
28.06.2010, 18:17 4
Цитата Сообщение от MagiicKing Посмотреть сообщение
Все равно выдает, что неявное преобразование невозможно. А явное преобразование сделать тоже не получается:
C#
1
2
3
T a;
int b = 0;
a = (T)b; // Преобразование типа "int" в "T" невозможно
ну как вариант можно вот так преобразовывать:

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
        public Form1()
        {
            InitializeComponent();
            try 
            {
                Method<int>(new[] { 5, 4, 11, 44, 2222, 11, 4234, 2, 1 });
                Method<string>(new[] { "djh", "djgj11s", "444" });
            }
            catch (Exception ex)
            {
                label1.Text = ex.Message;
            }
        }
 
        public void Method<T>(T[] items)
        {
            foreach (var item in items)
            {
                if (!char.IsNumber(item.ToString(), 0))
                {
                    throw new ArgumentException("Доступны только числа!");
                }
            }
        }
0
3 / 3 / 0
Регистрация: 31.01.2010
Сообщений: 36
28.06.2010, 19:00  [ТС] 5
Конкретно сейчас проблема все-таки несколько в другом:

C#
1
2
3
4
5
6
7
8
9
public static void Metod<T>(T[] a1) where T: int  // пока остановлюсь на одном типе
{
T j = 123; // Неявное преобразование типа 'int' в 'T' невозможно
for(int i = 0; i < a1.Lenght; i++) 
                {
                    a1[i] = j;
                    j += 123; // Неявное преобразование типа 'int' в 'T' невозможно; Оператор "+=" не может применяться к операндам типа "T" и "int"
                }
}
Альтернативный вариант:
C#
1
2
3
4
5
6
7
8
9
public static void Metod<T>(T[] a1) where T: int
{
int j = 123;
for(int i = 0; i < a1.Lenght; i++) 
                {
                    a1[i] = j; // Неявное преобразование типа 'int' в 'T' невозможно
                    j += 123; 
                }
}
Он выполнить преобразование не может даже при очень явных ограничениях.
0
328 / 312 / 68
Регистрация: 05.11.2009
Сообщений: 712
28.06.2010, 20:36 6
после
C#
1
where T :
можно описывать только интерфейсы и классы
0
мну довольно <(-__-)l
217 / 206 / 15
Регистрация: 17.01.2010
Сообщений: 2,462
29.06.2010, 08:11 7
что мешает записать
C#
1
2
int j = 123;
var v = j as T;
?
0
3 / 3 / 0
Регистрация: 31.01.2010
Сообщений: 36
29.06.2010, 09:10  [ТС] 8
C#
1
2
3
int asdf = 123;
var j = asdf as T; // Параметр-тип "T" не может использоваться с оператором "as", поскольку он не имеет ни ограничений типа класса, ни ограничения "class"
j += 123; // Оператор "+=" не может применяться к операндам типа "T" и "int"; Неявное преобразование типа "int" в "T" невозможно
Вот это мешает...
0
Администратор
83941 / 52529 / 244
Регистрация: 10.04.2006
Сообщений: 13,461
29.06.2010, 09:33 9
Цитата Сообщение от MagiicKing Посмотреть сообщение
Он выполнить преобразование не может даже при очень явных ограничениях.
А с чего вы взяли, что если напишете "123", то это обязательно будет воспринято как значение типа Int?

Добавлено через 13 минут
Цитата Сообщение от MagiicKing Посмотреть сообщение
Какое поставить ограничение, чтобы можно было вводить только числовые данные, и исключить строки, символы и т.п.?
Вообще, все типы-значения наследуют ValueType. Но это специальный класс и недоступен из кода.
Получается, что с помощью исключительно ограничения where так сделать не получится.
0
3 / 3 / 0
Регистрация: 31.01.2010
Сообщений: 36
29.06.2010, 20:54  [ТС] 10
Цитата Сообщение от mik-a-el Посмотреть сообщение
А с чего вы взяли, что если напишете "123", то это обязательно будет воспринято как значение типа Int?
Исключительно из-за этого:
C#
1
T j = 123; // Неявное преобразование типа 'int' в 'T' невозможно
Если не указывать конкретный тип этих "123" (byte, short, int), компилятор почему-то начинает сразу ругаться именно на "Неявное преобразование типа 'int' в 'T'".
Пробовал иначе:
C#
1
2
byte b = 123;
T j = b; // Неявное преобразование типа 'byte' в 'T' невозможно
Проверил, работают ли вообще ограничения:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
public static void Metod<T>(T[] a1) where T: short
{
short j = 123;
for(int i = 0; i < a1.Lenght; i++) 
                {
                    a1[i] = j; // Неявное преобразование типа "short" в "T" невозможно
                    j += 123;
                }
}
short[] s1 = new short[1];
byte[] b1 = new byte[1];
Metod<short>(s1); // Здесь никаких ошибок не выдается.
Metod<byte>(b1); // Тип "byte" не может быть использован как параметр-тип "T" в универсальном типе или методе "Metod<T>". Нет преобразования-упаковки из "byte" в "short".
Следовательно, метод может иметь только тип "short", но компилятор это игнорирует и все равно показывает ошибку. Можно как-то сделать, чтобы он просто ее игнорировал? Только она и мешает проект завершить.
0
87 / 87 / 26
Регистрация: 04.01.2010
Сообщений: 270
30.06.2010, 13:08 11
Цитата Сообщение от MagiicKing Посмотреть сообщение
Можно как-то сделать, чтобы он просто ее игнорировал?
Компилятор предупреждает об ошибке, но вы можете скомпилировать проект, когда выполнение программы дойдет до этого места, будет краш.
0
1322 / 995 / 127
Регистрация: 08.12.2009
Сообщений: 1,299
30.06.2010, 14:06 12
буду краток:
1) половина здесь написанного не имеет никакого отношения к жизни
2) для базовых численных типов нельзя сделать generic-метод, ибо все они не подчиняются одним и тем же законам (разве, что записываются циферками)
3) выхода два:
3.1) делать как в fcl - тупо перегружать метод для всех этих типов (благо их там мало)
3.2) не делать этого вообще - гибкость надо искать в другом

з.ы. обобщенное программирование в .net введено НЕ для торможения и без того тормозящих математических примитивов

Добавлено через 30 минут
для новичков дополню:
var a = 10; - int
var a = (int)10; - int;
var b = 100.500f; - float
var b= (float)100.500; - float
var c = 10.500; - double
var c = 10.5d;
var c = (double)10;
var d = 10.56m; - decimal
var d = (decimal)10.56; - decimal
ну и так далее
1
3 / 3 / 0
Регистрация: 31.01.2010
Сообщений: 36
30.06.2010, 15:10  [ТС] 13
Всем спасибо за ответы. Видимо, придется временно забить на обобщенное программирование)
0
Padawan
473 / 323 / 30
Регистрация: 30.01.2010
Сообщений: 1,841
30.06.2010, 15:35 14
На всякий, может я еще успел вот
0
0 / 0 / 0
Регистрация: 23.05.2010
Сообщений: 11
11.09.2010, 12:55 15
Доброе время суток.

Проблема аналогичнаяя
C#
1
2
3
4
5
 public string  Metod<T>(T a1) {
            foreach (var item in a1) {
                
            }          
        }
передаю в качестве T класс

C#
1
2
3
4
Class ds{
int a{get;set;}
int b{get;set;}
}
надо чтобы функция присвоила каждой переменной значния. Ошибки те же что у и автора топика;
0
129 / 129 / 22
Регистрация: 10.11.2010
Сообщений: 313
10.11.2010, 16:53 16
Есть решение:
C#
1
T result = (T)(object)some_variable; //прекрасно работает
И еще, если кому нужно:
для значения по умолчанию типа T пользовать конструкцию
C#
1
T some_variable = default(T);
1
51 / 49 / 7
Регистрация: 09.11.2010
Сообщений: 93
10.11.2010, 17:02 17
Цитата Сообщение от Lucius Kain Посмотреть сообщение
T result = (T)(object)some_variable; //прекрасно работает
Лишний боксинг/анбоксинг не есть тру.
В чем тогда смысл дженерика?
0
129 / 129 / 22
Регистрация: 10.11.2010
Сообщений: 313
10.11.2010, 17:10 18
Цитата Сообщение от Algol36 Посмотреть сообщение
В чем тогда смысл дженерика?
Дело не в общем смысле, а в решении конкретных задач, если требуется либо возвращать, либо конвертировать для обработки, то b/u необходим, а то что не гуд - останется на совести разработчика.
0
585 / 372 / 63
Регистрация: 22.07.2009
Сообщений: 875
Записей в блоге: 4
11.11.2010, 13:47 19
Цитата Сообщение от MagiicKing Посмотреть сообщение
Следовательно, метод может иметь только тип "short", но компилятор это игнорирует и все равно показывает ошибку. Можно как-то сделать, чтобы он просто ее игнорировал? Только она и мешает проект завершить.
Есть такая компоненка Leleko.Net.Kernel написанная на il, которая позволит такое:
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
using Leleko.Net;
namespace ConsoleApp
{
    public static class MAIN
    {
        public static void Metod<T>(T[] a1, T step)
        {
            // объект по умолчанию
            T j = default(T);
            if (j == null) throw new ArgumentException();
            else
            {
                // операнд сложения по умолчанию
                Func<T,T,T> Addition = Kernel.Math.Delegate.Additor<T>.Default;
                for (int i = 0; i < a1.Length; i++)
                    a1[i] = j = Addition(j, step);
            }
        }
        unsafe static void Main()
        {
            double[] F = new double[10];
            Metod(F,123);
            foreach (var e in F)
                Console.WriteLine(e);
        }
    }
}
Вложения
Тип файла: rar Leleko.Net.Kernel.rar (7.8 Кб, 10 просмотров)
0
51 / 49 / 7
Регистрация: 09.11.2010
Сообщений: 93
11.11.2010, 16:03 20
Цитата Сообщение от DjDiablo Посмотреть сообщение
Доброе время суток.

Проблема аналогичнаяя
C#
1
2
3
4
5
 public string  Metod<T>(T a1) {
            foreach (var item in a1) {
                
            }          
        }
передаю в качестве T класс

C#
1
2
3
4
Class ds{
int a{get;set;}
int b{get;set;}
}
надо чтобы функция присвоила каждой переменной значния. Ошибки те же что у и автора топика;
Как же вы можете делать foreach (var item in a1) , если тип ds не поддерживает IEnumerable ?
1
11.11.2010, 16:03
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
11.11.2010, 16:03
Помогаю со студенческими работами здесь

Преобразование типов: что лучше использовать
Что лучше использовать для конвертирования одного типа в другой? Использовать TryParse и Parse в...

Преобразование типов в Postgresql
Надо преобразовать тип varchar в numeric (5,2). Делаю так: select sum (CAST(a01 AS numeric(5,1)))...

TextBox. Преобразование типов из string в date и int
Нужно ввести в форме данные для добавления их в таблицу. Фото ошибки под спойлером namespace...

Использование static PropertyData в обобщенном классе на WPF Catel
Здравствуйте, использую WPF Catel. Столкнулся с проблемой: public sealed class TestType&lt;T&gt; :...


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

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

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