идея переключения / сопоставления с образцом

недавно смотрел на 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). "Я"

Ответы на вопрос(11)

Ваш ответ на вопрос