2017-02-14 3 views
-1

Дженерики используются для развязки логики из типа данных.Как использовать Generics для реализации этого?

public class Calc<T> 
{ 
    public T Add(T a, T b) 
    { 
     return (a+b); 
    } 
} 

Но это бросает ниже компиляции ошибка времени

Оператор + не может быть применен на тип T.

Я не понимая, почему так. потому что если это разрешено из main.cs

main() 
{ 
    Calc<int> obj = new Calc<int>(); 
    int c = obj.Add(10,20); 
} 

Может кто-нибудь объяснить, почему я получаю ошибки сборки?

+0

@ManfredRadlwimmer, я знаю, что такое Generics –

+3

Видимо, нет. Если вы не добавляете никаких ограничений на свой тип, это просто «объект». Объекты не имеют оператора '+'. Дженерики в C# не совсем то же самое, что и на других языках. –

+0

@ManfredRadlwimmer Как мне выполнить свою операцию.Если я передаю float, он должен возвращать float, если int return int –

ответ

1

Неограниченные дженерики, такие как ваш Calc<T>, должны иметь возможность компилировать с использованием любого типа, а не все типы поддерживают операнд +, поэтому ваш код не компилируется. Это независимо от того, с какими конкретными типами вы создаете код вызова.

Вы можете ограничить тип T и таким образом получить доступ к большему количеству методов, делая Calc<T> where T:object или Calc<T> where T: IComparable, который позволит вам:

public T CompareTo(T a, T b) 
{ 
    return (a.CompareTo(b)); 
} 

Поскольку все T теперь должны реализовать IComparable. К сожалению, Int32 не реализует никакого интерфейса, который определяет оператор + или любой метод добавления. Таким образом, вы не можете реализовать это заявление.

+0

Информационный пост. благодаря –

2

Генераторы C# не поддерживают произвольные операторы. Точный (возможно, виртуальный) метод должен быть известен во время компиляции родового типа. Поскольку аргумент generic type в вашем примере не ограничен вообще, вы можете использовать только члены типа object, который не включает оператора +.

Невозможно использовать генераторы C#, чтобы делать то, что вы пытаетесь сделать, извините. Лучшее, что вы можете сделать, это куча проверок типов для нескольких известных типов (и соответствующих бросков, которые сложны со значениями типов) или с использованием отражения (в частности, будет работать отлично).

0

C# generics отличаются от шаблонов C++. Код C# не может быть скомпилирован, если общий тип не имеет определения для используемого метода (operator + в вашем случае), тогда как компилятор C++ применяет этот метод к фактическому типу аргумента шаблона.

0

Дополнение не допускается, потому что нет гарантии, что прошедшие типы имеют оператор + перегрузка.
Существует способ сделать это, но он будет работать до тех пор, пока вы передадите типы, у которых есть оператор +. В противном случае будет выброшено RuntimeBinderException. Кроме того, есть некоторое влияние на производительность, но, если код не критичен по производительности, не должно быть проблемой.

public T Add<T>(T a, T b) 
{ 
    dynamic da = a, db = b; 
    return da + db; 
} 
Смежные вопросы