2009-07-30 2 views
8

Можно создать дубликат:
What are the differences between Generics in C# and Java… and Templates in C++?C# дженериков по сравнению с шаблонами C++

Каковы различия между непатентованных C# по сравнению с шаблонами C++? Я понимаю, что они не решают точно такую ​​же проблему, так какие плюсы и минусы обоих?

+4

Какое совпадение, это моя тема в блоге на сегодня. http://blogs.msdn.com/ericlippert/archive/2009/07/30/generics-are-not-templates.aspx –

+1

это * имеет *, чтобы быть точным дубликатом. @ Эрик Липперт: Ой, интересно, даст ему – jalf

ответ

16

Вы можете рассмотреть шаблоны C++, чтобы быть истолковано, функциональный язык программирования под видом системы дженериков. Если это вас не пугает, оно должно:

C# generics очень ограничены; вы можете параметризовать класс типа или типа и использовать эти типы в методах. Таким образом, чтобы взять пример из MSDN, вы могли бы сделать:

public class Stack<T> 
{ 
    T[] m_Items; 
    public void Push(T item) 
    {...} 
    public T Pop() 
    {...} 
} 

И теперь вы можете объявить Stack<int> или Stack<SomeObject> и он будет хранить объекты этого типа, безопасно (т.е. не беспокоится о вводе SomeOtherObject в по ошибка).

Внутренне среда выполнения .NET будет специализироваться на вариантах для таких фундаментальных типов, как int, и варианта для типов объектов. Это позволяет, например, представить для Stack<byte> намного меньше, чем представление Stack<SomeObject>.

C++ шаблоны позволяют подобное использование:

template<typename T> 
class Stack 
{ 
    T *m_Items; 
    public void Push(const T &item) 
    {...} 
    public T Pop() 
    {...} 
}; 

Это выглядит похоже на первый взгляд, но есть несколько важных отличий. Во-первых, вместо одного варианта для каждого фундаментального типа и одного для всех типов объектов существует один вариант для каждого типа, который он был создан для. Это может быть много типов!

Следующее значительное отличие (на большинстве компиляторов C++) будет скомпилировано в каждой единицы перевода, в которой он используется. Это может замедлить компиляцию.

Другим интересным атрибутом для шаблонов C++ является то, что они могут применяться к вещам, отличным от классов, - и когда они есть, их аргументы могут быть автоматически обнаружены. Например:

template<typename T> 
T min(const T &a, const T &b) { 
    return a > b ? b : a; 
} 

Тип T будет автоматически определяться контекстом, в котором используется функция.

Эти атрибуты могут использоваться в хороших целях за счет вашего здравомыслия. Поскольку шаблон C++ перекомпилируется для каждого типа, к которому он применяется, и реализация шаблона всегда доступна компилятору, C++ может сделать очень агрессивную вставку на шаблоны. Добавьте к этому автоматическое определение значений шаблона в функциях, и вы можете сделать anonymous pseudo-functions в C++, используя boost::lambda. Таким образом, выражение типа:

_1 + _2 + _3

Создает объект с серьезно пугающей типа, который имеет оператор(), который добавляет свои аргументы.

Существует множество других темных уголков системы шаблонов C++ - это чрезвычайно мощный инструмент, но может быть болезненным думать, а иногда и трудно использовать, особенно когда он дает сообщение об ошибке на двадцать страниц. Система C# намного проще - менее мощная, но более понятная и сложная для использования.

+0

* Еще один интересный атрибут шаблонов C++ заключается в том, что они могут применяться к вещам, отличным от классов *, - это то же самое, что и C#, позволяет нам определять общие функции в функциях (например, 'T SomeFunc (T input) {...}')? – dotNET

3

http://blogs.msdn.com/csharpfaq/archive/2004/03/12/88913.aspx

Грубо говоря, большая часть разницы связано с тем, что шаблоны разрешаются во время компиляции, и дженерики разрешаются во время выполнения.

+2

На самом деле, хотя генераторы могут быть созданы во время выполнения (через отражение, как и все остальное), во время компиляции многое выясняется. Например, JIT создает конкретную реализацию «List » вместо использования обычной версии с типом, эквивалентной «List » (это один из способов, который отличается от Java). –

+0

@Earwicker: расскажи мне об этом. Вот почему вы не можете выполнять общую рекламу (например, объединение списка в список ). Функциональность существует в CLI, но они решили не реализовывать ее таким образом в C# (ошибка, IMO). –

1

Этот blog entry from Eric Gunnerson охватывает эту тему очень хорошо.

Самая большая разница в том, что шаблоны являются функцией времени компиляции, тогда как generics - это функция времени исполнения.

Смежные вопросы