Создайте метод динамически, где возвращаемый тип известен во время компиляции - PullRequest
0 голосов
/ 17 ноября 2018

задан следующий класс:

public class Stock {
   public string Name;
   public double Price;
}

, и у меня есть следующий DataFactory:

public class DataFactory {
   public Stock Stock = new Stock();   

   public DataFactory Name(string name) {
     Stock.name = name;
     return this;
   }

   public DataFactory Price(double price) {
      Stock.Price = price;
      return this;
   }
}

может следующий код:

.....
   new DataFactory().Name("ATVI").Price(50)
....

записывается как:

....
   new DataFactory().ATVI().Price(50)
....

без реализации ATVI () на заводе?Это будет работать, если я заранее создаю метод динамически.Но возможно ли это, не зная, какой метод будет вызван?Поэтому я ищу какой-то хук при жизни, который уведомляет меня о неизвестных свойствах / методах.

И если это работает, можно ли при вызове Price () вызывать intellisense?

Не знаю, какэто можно назвать извините, если существуют дублирующие темы.

С наилучшими пожеланиями, Йозеф

Ответы [ 2 ]

0 голосов
/ 17 ноября 2018

следующий код

new DataFactory().Name("ATVI").Price(50)

нельзя записать как

new DataFactory().ATVI().Price(50)

на самом деле, ни один из этих кодов не работает. потому что вы не можете получить функцию «Price» из функции «Name» и «ATVI ()» не является допустимой функцией

Мне не больно, что вы пытаетесь выполнить, данный код вернет функцию. но если я не ошибаюсь, вы хотите установить «Цена» по «Имя». тогда я думаю, что вам нужен словарь класса

Я пытался придумать хорошую функцию или что-то в этом роде, но я не совсем понимаю, что вы ищете ...

0 голосов
/ 17 ноября 2018

Предполагая, что у вас есть конечный предопределенный набор текстовых литералов, который меняется не часто , вы можете просто сгенерировать перечисление (или даже класс строковых констант), используя, например, шаблоны T4, и используйте это как: DataFactory.Name(Tickers.ATVI).Price(50)
Это был бы подход, который лучше всего соответствует семантике проблемы и возможностям языка C # и инструментов.

Кстати, этот метод цепочки, который вы планируете использовать, представляет собой комбинацию шаблона компоновщика и плавного интерфейса , , см. Пример в c #

Если вы все еще хотите скрыть это как вызов метода, у вас есть несколько вариантов:

  1. Предварительно - Создайте список методов, используя T4 шаблоны в частичном классе или в качестве методов расширения для вашей фабрики данных. Вы можете выбрать список литералов из своего хранилища данных внутри шаблона T4. Это довольно распространенный подход. Поскольку у вас будут предварительно сгенерированные методы, itellisence будет работать с этим подходом. Узнайте больше о T4
  2. Используйте DLR и dynamic. Это откладывает поиск метода до времени выполнения, и вы можете создать собственный динамический объект, который будет принимать любой вызов метода, а затем взять имя этого метода и передать его в качестве аргумента вашему Name методу. Intellisence не будет работать с этим подходом, поскольку у вас нет метаданных в сборке относительно ваших методов. Как создать динамический объект
  3. Используйте dynamic и дополнительно создайте расширение intellisence, см. Пользовательское расширение Intellisense для получения более подробной информации

Вы можете пойти еще дальше, написать анализатор Roslyn и установить его в своей Visual Studio, чтобы иметь автоматические исправления кода от DataFactory().Name("ATVI") до DataFactory().ATVI(), то есть - если у вас есть время / ресурсы. Посмотрите пример анализатора кода

Как всегда, ответ "это зависит", и контекст - это все, поэтому трудно сказать, какое решение будет лучшим для вас. Я предпочел бы пойти на самый простой 1), особенно учитывая сложность и стоимость обслуживания 2) и 3)

Пожалуйста, дайте мне знать, если вам нужна более подробная информация о любом из вариантов Надеюсь, это поможет!

...