C# 4.0 “динамическое” ключевое слово сокращают Дженерики?

writeRead.getArrayList(this).stream()
            .map(Game::getWinnerGamer)
            .collect(Collectors.groupingBy(Gamer::getName, Collectors.summingInt(Gamer::getLeaderboardScore)))
            .entrySet()
            .stream()
            .sorted(Comparator.comparing(Map.Entry<String, Integer>::getValue).reversed())
            .map(entry -> new Gamer(entry.getKey(), entry.getValue()))
            .collect(Collectors.toList());

Шаги:

  1. извлекают победителей
  2. групп победителей по имени и суммируют их оценки. В результате вы получите Map
  3. get entrySet этой карты
  4. открытый поток на этом entySet
  5. сортировка по оценкам в направлении DESC
  6. вход в карту для Gamer (создать новый экземпляр геймера для каждой записи)
  7. собирать в список

Мой ответ основан на предположении, что у вас есть такая структура:

class Game {
    private Gamer winnerGamer;
    // getter & setter
}

class Gamer {
    private String name;
    private Integer leaderboardScore;
    // getters & setters && AllArgsContructor
}

Кстати: если вы переопределяете равенства и хеш-код в классе Gamer, вы можете избежать воссоздания Gamer с помощью этого:

writeRead.getArrayList(this).stream()
            .map(Game::getWinnerGamer)
            .collect(Collectors.groupingBy(Function.identity(), Collectors.summingInt(Gamer::getLeaderboardScore)))
            .entrySet()
            .stream()
            .sorted(Comparator.comparing(Map.Entry<Gamer, Integer>::getValue).reversed())
            .map(Map.Entry::getKey)
            .collect(Collectors.toList());
9
задан Community 23 May 2017 в 11:59
поделиться

5 ответов

dynamic может упростить ограниченное количество сценариев отражения (где вы знаете имя члена заранее, но нет интерфейса) - в частности, это может помочь с универсальными операторами (, хотя существуют другие ответы ), но, кроме уловки с обобщенными операторами, существует небольшое пересечение с универсальными шаблонами.

Универсальные шаблоны позволяют вам знать (во время компиляции) о типе, с которым вы работаете - и наоборот, динамический не заботится о типе. В частности, универсальные шаблоны позволяют вам указать и подтвердить ряд условий относительно типа, т.е. он может реализовывать некоторый интерфейс или иметь общедоступный конструктор без параметров. dynamic тоже не помогает: он не поддерживает интерфейсы, и, что хуже, чем просто не заботиться об интерфейсах, это означает, что мы не можем даже увидеть явные реализации интерфейса с динамический .

Кроме того, динамический на самом деле является частным случаем объекта , поэтому бокс вступает в игру, но с удвоенной силой.

В действительности, вам следует ограничить использование динамического несколькими случаями:

  • COM-взаимодействие
  • DLR-взаимодействие
  • возможно легкая набивка
  • возможно некоторые общие операторы

Для всех остальных случаев лучше всего подходят универсальные шаблоны и обычный C #.

17
ответ дан 4 December 2019 в 06:01
поделиться

Чтобы ответить на ваш вопрос. Нет.

  • Generics дает вам « повторное использование алгоритма » - вы пишете код независимо от типа данных. ключевое слово dynamic ничего с этим не делает. Я определяю List и затем могу использовать его для списка строк, целых чисел и т. Д.
  • Безопасность типов : споры о проверке времени компиляции в целом. Динамические переменные не будут предупреждать вас предупреждениями / ошибками во время компиляции, если вы сделаете ошибку, они просто взорвутся во время выполнения, если метод, который вы пытаетесь вызвать, отсутствует. Споры о статической и динамической типизации
  • Производительность : Generics значительно улучшает производительность алгоритмов / кода, использующих типы значений. Это предотвращает весь цикл упаковки-распаковки, который стоит нам pre-Generics. Динамический не делает Для этого тоже ничего не надо.

Ключевое слово dynamic даст вам

  • более простой код (например, при взаимодействии с Excel ...) Вам не нужно указывать имя классов или объектной модели. Если вы вызываете правильные методы, среда выполнения позаботится о вызове этого метода, если он существует в объекте в это время. Компилятор позволяет вам уйти, даже если метод не определен. Однако это подразумевает, что это будет медленнее, чем выполнение проверенного компилятором / статического вызова метода, поскольку CLR должна будет выполнить проверки перед вызовом динамического поля / метода var.
  • Динамическая переменная может содержать различные типы объектов. в разные моменты времени - вы не привязаны к определенному семейству или типу объектов.
17
ответ дан 4 December 2019 в 06:01
поделиться

Динамические классы и универсальные шаблоны это совершенно разные понятия. С помощью дженериков вы определяете типы во время компиляции. Они не меняются, они не динамичны. Вы просто помещаете «заполнитель» в некоторый класс или метод, чтобы вызывающий код определял тип.

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

6
ответ дан 4 December 2019 в 06:01
поделиться

Чтобы ответить на ваш первый вопрос, обобщенные типы - это разрешенные во время компиляции, динамические типы во время выполнения. Таким образом, существует определенная разница в безопасности типов и скорости.

8
ответ дан 4 December 2019 в 06:01
поделиться

Ответ на второй вопрос: вы можете возвращать анонимные типы в C # 3.0. Приведите тип к объекту, верните его и используйте отражение для доступа к его членам. Ключевое слово dynamic - всего лишь синтаксический сахар для этого.

3
ответ дан 4 December 2019 в 06:01
поделиться
Другие вопросы по тегам:

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