Общая функция идентификации для использования с выводом типа - PullRequest
10 голосов
/ 19 февраля 2009

Мне было интересно, возможно ли это, поскольку мои 5 минут экспериментов оказались бесплодными.

Я надеялся, что это будет так же просто, как:

T Identity<T>(T t) { return t; }

Но это не скомпилируется в универсальных методах, принимающих параметры Func. Например, OrderBy. Даже при указании параметров типа (а это именно то, чего я хочу избежать!), Он не компилируется.

Затем я попробовал что-то, что, как я думал, будет работать:

Func<T, R> MakeIdentity<T, R>()
{
  return (T t) => (R)(object)t;
}

Также не идти :( (это компилируется при применении параметров типа, опять же, не то, что я хочу)

Кто-нибудь имел счастье сделать такую ​​вещь?

ОБНОВЛЕНИЕ: пожалуйста, не говорите: х => х, я знаю, это очевидно! Я прошу функцию, а не выражение:)

ОБНОВЛЕНИЕ 2: Когда я ссылаюсь на тождество, я имею в виду функциональный смысл, когда функция просто возвращает тот же объект, который вы ей передали. Это возможно на каждом функциональном языке, с которым я сталкивался, но они не используют статическую типизацию. Мне интересно, как это сделать (если это возможно) с генериками. Просто для удовольствия!

ОБНОВЛЕНИЕ 3: Вот частичное «решение», основанное на 2-й идее:

Expression<Func<T, T>> MakeIdentity<T>()
{
  return t => t;
}

void Foo(string[] args)
{
  var qargs = args.AsQueryable();
  var q = qargs.OrderBy(MakeIdentity<string>());
  ...
}

Я не думаю, что будет возможно что-то большее, чем это.

Ответы [ 4 ]

3 голосов
/ 19 февраля 2009

Вывод типа не будет работать, так как метод хоста и метод ввода являются общими. Для этого необходимо написать

myList.OrderBy<int, int>(Identity);

Или

myList.OrderBy((Func<int, int>)Identity);
2 голосов
/ 01 декабря 2015

Это работает для меня там, где я до сих пор нуждался.

internal class IdentityFunction<TSource>
{
    public static Func<TSource, TSource> Instance
    {
        get { return x => x; }
    }
}

OrderBy(IdentityFunction<Foo>.Instance)
1 голос
/ 19 февраля 2009

Проблема в том, что анонимные функции и группы методов в C # не участвуют в выводе типов. Явные типы должны быть предоставлены.

Что вы можете сделать, так это иметь функции идентификации для анонимных функций. Пример

Func<T> IdentityFunc1<T>(Func<T> func) { return func; }

Я не совсем уверен, что вы получаете со вторым образцом. Вы можете уточнить?

0 голосов
/ 23 ноября 2010

Первый вариант у меня работает:

public class Foo {

   public Foo(Func<MyObj, MyObj> map) {... }

}

public class Client {

   private static T Identity<T>(T t) { return t; }

   public void main() {
      var foo = new Foo(Identity);

      var c = from f in Enumerable.Range(0, 100) select Identity(f);
      c.ToList().ForEach(System.Console.Out.WriteLine);
   }
}
...