Используя функцию эмуляции Ф матч# в C#


Так что это был вдохновлен: этот вопрос Но на самом деле не ответить на него: Что вы думаете о:

public class Case<TRes>
{
    public Case(bool condition, Func<TRes> result)
    {
        Condition = condition;
        Result = result;
    }
    public bool Condition {get; private set;}
    public Func<TRes> Result { get; private set; }

    public static Case<TRes> Default(Func<TRes> value)
    {
        return new Case<TRes>(true, value);
    }
}

public static class Logic
{
    public static T Match<T> (params Case<T>[] cases)
    {
        return cases.First(c => c.Condition).Result();
    }
}

Которые можно вызвать:

int i = Logic.Match
(
    new Case<int>(IsCloudy(skyImage), () =>
    {
        ChangeWeatherIcon(Icons.Clouds);
        return 13;
    }),
    new Case<int>(a < b, () => a),
    Case<int>.Default(() => {throw new Exception(); })
);

его цель не спокойно эмулировать Ф#'матч. (Потому что матч на F# не фактически принять условия, это матч структурно/шаблон) Так что на самом деле его вроде как тринарный оператор, отвечает nonOrdinal оператора выбрать.

У кого-нибудь есть любая идея, как заставить его работать чище? Может, чтобы избавиться от новой и в скобках



576
3
c# f#
задан 2 октября 2011 в 02:10 Источник Поделиться
Комментарии
2 ответа

Если честно, это практически невозможно сделать элегантные шаблоны на языке, который не поддерживает его (например, c#). Проблема с тем, что вы написали-это более сложная, чем эквивалентный если-то-иначе цепь:

if (IsCloudy(skyImage)) {
ChangeWeatherIcon(Icons.Clouds);
return 13;
}
if (a < b) {
throw new Exception();
}

Теперь я дорого бы дал, чтобы увидеть некоторые более поздние версии C# принимает алгебраические типы данных (а-ля Ф#) с шаблоном, но пока я сильно сомневаюсь, что вы сможете делать лучше, чем если-то-иначе цепи.

1
ответ дан 3 октября 2011 в 03:10 Источник Поделиться

Я в целом согласен с Рейфом: не стоит пытаться сделать это в C# для общего дела. Использование выражений и т. д., просто не отделаешься, ИМХО шаблону-это то, что должны быть встроены в язык (или использовать податливый язык как Lisp). Главный смысл сопоставления заключается в том, что он является исчерпывающим (или, по крайней мере, вы получите предупреждение, если это не так), и поэтому общая. Если вы не можете этого гарантировать, то вы не получите ничего.

Однако, я думаю, что это плодотворное использование шаблонов для конкретных случаев. Например, в FSharpx у нас есть шаблоны для C# на опции, списки и выборы (т. е. анонимный размеченные объединения).

1
ответ дан 5 октября 2011 в 01:10 Источник Поделиться