Возможно ли создать единую многотипную коллекцию многотипных лямбда-функций в C # 4.0? - PullRequest
6 голосов
/ 04 мая 2011

Например, что-то вроде:

Dictionary<string, Func<T1, T2, bool>> comparisons;
    comparisons.add("<", (x, y) => x < y);
    comparisons.add("==", (x, y) => x == y);
    comparisons.add(">", (x, y) => x > y);

На данный момент я недостаточно знаю о лямбдах C # и универсальных контейнерах разного типа, чтобы правильно их собрать. Это вообще возможно?

Ответы [ 5 ]

7 голосов
/ 04 мая 2011

Да, совершенно справедливо иметь что-то вроде этого:

Dictionary<string, Func<int, int, bool>> comparisons = new Dictionary<string, Func<int, int, bool>>();

comparisons.Add("<", (x, y) => x < y);
comparisons.Add("==", (x, y) => x == y);
comparisons.Add(">", (x, y) => x > y);

В вашем примере вам нужно использовать Func<int, int, bool>, так как вы берете два параметра и возвращаете логическое значение.

Вы также можете поместить это в обобщенную реализацию, но тогда вам понадобится какой-то способ ее ограничения, чтобы что-либо должно было реализовывать операторы <, == и>.

3 голосов
/ 04 мая 2011

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

Dictionary<string, Func<int, int, bool>> comparisons;
comparisons.add("<", (x, y) => x < y);
comparisons.add("==", (x, y) => x == y);
comparisons.add(">", (x, y) => x > y);

. Вы можете использовать интерфейс IComparable, чтобы разрешить разные типы, но тогда вы можете использовать только метод CompareTo, чтобыреализовать операторы:

Dictionary<string, Func<IComparable, IComparable, bool>> comparisons;
comparisons.add("<", (x, y) => x.CompareTo(y) < 0);
comparisons.add("==", (x, y) => x.CompareTo(y) == 0);
comparisons.add(">", (x, y) => x.CompareTo(y) > 0);

Это, конечно, дает меньше ограничений для используемых данных, например, вы можете передать значение string и DateTime делегату оператора, и оно компилируется простохорошо.Это не до тех пор, пока вы не запустите его, он не сможет.

0 голосов
/ 04 мая 2011

Я не вижу смысла в том, чтобы иметь T1 и T2;если есть разные типы, которые вы, как правило, не можете сравнивать?*

class MyClass<T> where T:IComparable<T> 
{
    private Dictionary<string, Func<T, T, bool>> comparisons
        = new Dictionary<string, Func<T, T, bool>>
              {
                  {"<", (x, y) => x.CompareTo(y) < 0},
                  {"==", (x, y) => x.Equals(y)},
                  {">", (x, y) => x.CompareTo(y) > 0}
              };
}
0 голосов
/ 04 мая 2011

Да, это можно сделать, но вы можете сделать это, только если все параметры универсального типа имеют конкретные типы. Например, это работает:

Dictionary<string, Func<int, int, bool>> comparisons = new Dictionary<string, Func<int, int, bool>>();

Нет способа сделать это (в псевдо-C ++ синтаксисе):

Dictionary<string, Func<?, ?, bool>> comparisons = new Dictionary<string, Func<?, ?, bool>>();
0 голосов
/ 04 мая 2011
Func<int, int, bool> t = null;

var comparisons = new Dictionary<string, Func<int, int, bool>>
                              {
                                  {"<", (x, y) => x < y},
                                  {"==", (x, y) => x == y},
                                  {">", (x, y) => x > y}
                              };

t = comparisons["<"];
 bool result = t(1,2);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...