идея переключения / сопоставления с образцом
недавно смотрел на F #, и пока яЯ вряд ли пройду через забор в ближайшее время, он определенно выделяет некоторые области, где C # (или поддержка библиотеки) может облегчить жизнь.
В частности, яЯ думаю о возможности сопоставления с образцом в F #, который допускает очень богатый синтаксис - гораздо более выразительный, чем текущие переключатели / условные эквиваленты C #. Я выиграл'не могу привести прямой пример (мой F # недо этого), но вкратце это позволяет:
сопоставление по типу (с полной проверкой для различающихся объединений) [обратите внимание, что это также выводит тип для связанной переменной, предоставляя доступ к члену и т. д.]сопоставлять по предикатукомбинации вышеперечисленного (и, возможно, некоторые другие сценарии I 'я не в курсе)Хотя для C # было бы прекрасно в конечном итоге позаимствовать [гм] часть этого богатства, тем временем ямы смотрели на то, что можно сделать во время выполнения - например, довольно легко собрать некоторые объекты, чтобы:
var getRentPrice = new Switch()
.Case(bike => 100 + bike.Cylinders * 10) // "bike" here is typed as Motorcycle
.Case(30) // returns a constant
.Case(car => car.EngineType == EngineType.Diesel, car => 220 + car.Doors * 20)
.Case(car => car.EngineType == EngineType.Gasoline, car => 200 + car.Doors * 20)
.ElseThrow(); // or could use a Default(...) terminator
где getRentPrice является Func <Транспортное средство, Int>.
[примечание - возможно Switch / Case здесь неправильные термины ... но это показывает идею]
Для меня это намного яснее, чем эквивалент с использованием многократного if / else или составного троичного условного выражения (которое становится очень грязным для нетривиальных выражений - скобки в изобилии). Это также позволяет избежатьмного преобразования и допускает простое расширение (напрямую или с помощью методов расширения) до более конкретных совпадений, например сопоставление InRange (...), сопоставимое с VB Select ... Case "х к тебе " usage.I»
я просто пытаюсь оценить, думают ли люди, что такие конструкции, как указано выше, приносят большую пользу (при отсутствии языковой поддержки)?
Обратите внимание, что яЯ играл с 3 вариантами выше:
Функ <TSource, TValue> версия для оценки - сопоставима с составными троичными условными выражениямидействие <TSource> версия - сопоставима с if / else if / else if / else if / elseВыражение <Func <TSource, TValue >> версия - как первая, но может использоваться произвольными провайдерами LINQКроме того, использование версии на основе выражений позволяет переписывать дерево выражений, по существу объединяя все ветви в одно составное условное выражение, вместо использования повторного вызова. У меня нетнедавно проверил, но в некоторых ранних сборках Entity Framework я вспоминаю, что это необходимо, так как это неМне очень нравится InvocationExpression. Он также позволяет более эффективно использовать LINQ-to-Objects, поскольку он избегает повторных вызовов делегатов - тесты показывают совпадение, подобное приведенному выше (с использованием формы выражения), с той же скоростью (на самом деле, немного быстрее) по сравнению с эквивалентным C # составное условное утверждение. Для полноты, Func <...> based-version занимал в 4 раза больше времени, чем условный оператор C #, но все еще очень быстр и вряд ли будет основным узким местом в большинстве случаев использования.
Я приветствую любые мысли / замечания / критические замечания и т. Д. По поводу вышеизложенного (или о возможностях более широкой поддержки языка C # ... здесь 'с надеждой ;-p). "Я"