Создание ограниченных общих методов расширения, где T должен быть IEnumerable [dублировать]

Некоторые люди считают заголовочные файлы преимуществом:

  • Утверждается, что он включает / обеспечивает / позволяет разделять интерфейс и реализацию, но обычно это не так. Заголовочные файлы полны деталей реализации (например, переменные-члены класса должны быть указаны в заголовке, даже если они не являются частью общедоступного интерфейса), а функции могут и часто задаются inline в объявление класса в заголовке, снова разрушая это разделение.
  • Иногда говорят, что улучшать время компиляции, потому что каждая единица перевода может обрабатываться независимо. И все же C ++ - это, вероятно, самый медленный язык, который существует, когда дело доходит до времени компиляции. Одной из причин является много многократных включений одного и того же заголовка.

В конечном итоге система заголовков является артефактом 70-х годов, когда C был спроектирован. В то время у компьютеров было очень мало памяти, и сохранение всего модуля в памяти просто не было вариантом. Компилятор должен был начать читать файл вверху, а затем продолжить линейно через исходный код. Механизм заголовка позволяет это. Компилятор не должен учитывать другие единицы перевода, он просто должен прочитать код сверху вниз.

И C ++ сохранил эту систему для обратной совместимости.

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

Однако одно из предложений для C ++ 0x состояло в том, чтобы добавить правильную систему модулей, позволяя компилировать код, подобный .NET или Java, в более крупные модули, все в одном и без заголовков. Это предложение не делало сокращения в C ++ 0x, но я считаю, что он все еще находится в категории «мы бы хотели сделать это позже». Возможно, в TR2 или аналогичном.

1
задан Daniel Hilgarth 9 August 2011 в 14:31
поделиться

3 ответа

Вы можете сделать всю общую функцию:

  private void Pager & lt; T & gt; (IEnumerable & lt; t & gt; tEnum) {// здесь T может быть любым} // вы можете называть его как  : Pager (новый int [] {10,20});  Pager (новая строка [] {"meep", "x"});   
2
ответ дан Blindy 15 August 2018 в 18:54
поделиться
[D3] Конечно. Просто выполните метод generic:

  private void Pager & lt; T & gt; (IEnumerable & lt; t & gt; tEnum) {...}  

Если вы посмотрите на LINQ-to-objects, так же как и они делают (без дополнительного этого до IEnumerable & lt; T & gt; в соответствии с синтаксисом метода расширения.)

4
ответ дан dlev 15 August 2018 в 18:54
поделиться
  • 1
    Я согласен с тем, что ваше решение, вероятно, связано с OP, но мне просто интересно, сможет ли private void Pager (IEnumerable & lt; object & gt; tEnum) работать. Казалось бы, полезно не указывать методу, какой тип Т. Как вы думаете? – Bazzz 9 August 2011 в 14:36
  • 2
    @Bazzz В .NET 4 это должно быть хорошо, поскольку IEnumerable & lt; T & gt; помечен как ковариантный (он фактически объявлен как IEnumerable & lt; out T & gt; ). Не зная внутренности метода, трудно сказать, будет ли подход значительно хуже, но я думаю, что в целом лучше просто сделать метод общим. – dlev 9 August 2011 в 14:38
  • 3
    @Bazzz Еще один момент: хотя это не похоже на то, что оно применимо в ситуации OP, в общем случае общая версия может принимать и использовать IEnumerable & lt; int & gt; без необходимости удаления элементов на перечисление, тогда как IEnumerable & lt; object & gt; будет в этой ситуации. – dlev 9 August 2011 в 14:55

Возможно, этот способ?

  private void Pager & lt; t & gt; (IEnumerable & lt; t & tnnum)  
0
ответ дан Pablo Castilla 15 August 2018 в 18:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: