c# - una - Función de identidad genérica para usar con inferencia de tipo
no se puede convertir expresion lambda en el tipo delegado (4)
Me preguntaba si es posible, ya que mis 5 minutos de experimentación resultaron infructuosos.
Esperaba que fuera tan fácil como:
T Identity<T>(T t) { return t; }
Pero esto no se puede compilar en métodos genéricos tomando los parámetros de Func. Por ejemplo, OrderBy. Incluso al especificar parámetros de tipo (¡que es exactamente lo que quiero evitar!), No se puede compilar.
Luego probé algo que pensé que funcionaría:
Func<T, R> MakeIdentity<T, R>()
{
return (T t) => (R)(object)t;
}
También no go :( (esto compila al aplicar parámetros de tipo, de nuevo, no es lo que quiero)
¿Alguien ha tenido suerte haciendo tal cosa?
ACTUALIZACIÓN: por favor no digas: x => x, lo sé, ¡es obvio! Estoy pidiendo una función, no una expresión :)
ACTUALIZACIÓN 2: Cuando me refiero a la identidad, quiero decir en el sentido funcional, donde la función simplemente devuelve el mismo objeto que le pasaste. Probablemente esté en todos los lenguajes funcionales con los que me he encontrado, pero esos no usan tipeo estático. Me pregunto cómo hacer esto (si es posible) con genéricos. ¡Solo por diversión!
ACTUALIZACIÓN 3: Aquí hay una ''solución'' parcial basada en la segunda idea:
Expression<Func<T, T>> MakeIdentity<T>()
{
return t => t;
}
void Foo(string[] args)
{
var qargs = args.AsQueryable();
var q = qargs.OrderBy(MakeIdentity<string>());
...
}
No pienso nada más de lo que esto será posible.
El problema que tienes es que las funciones anónimas y los grupos de métodos en C # no participan en la inferencia de tipos. Se deben dar tipos explícitos.
Sin embargo, lo que puedes hacer es tener funciones de Identidad para funciones anónimas. Ejemplo
Func<T> IdentityFunc1<T>(Func<T> func) { return func; }
No estoy del todo seguro de a qué te refieres con la segunda muestra. ¿Puedes elaborar?
La inferencia de tipo no funcionará, ya que el método de host y el método de entrada son genéricos. Para hacer esto debes escribir
myList.OrderBy<int, int>(Identity);
O
myList.OrderBy((Func<int, int>)Identity);
La primera opción funciona para mí:
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);
}
}
Esto funciona para mí en los lugares que lo he necesitado hasta ahora.
internal class IdentityFunction<TSource>
{
public static Func<TSource, TSource> Instance
{
get { return x => x; }
}
}
OrderBy(IdentityFunction<Foo>.Instance)