Общая функция идентификации для использования с типом вывода

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

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

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

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

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

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

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

Неужели кому-то повезло сделать такую ​​вещь?

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

ОБНОВЛЕНИЕ 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>());
  ...
}

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

Ответ 1

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

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

или

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

Ответ 2

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

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

OrderBy(IdentityFunction<Foo>.Instance)

Ответ 3

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

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

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

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

Ответ 4

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

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);
   }
}