parameter funciones examples ejemplo delegate delegado anonimas c# lambda

c# - funciones - ¿Cómo funciona Func<T, TResult>?



func y action en c# (3)

Estoy creando un método de extensión Distinct donde puedo pasar los criterios como los siguientes.

persons.Distinct(p => p.Name);

Obtuve el código de la web, pero me cuesta mucho entender el propósito de Func<T, TResult> . Además, cuando digo p => p.Name estoy enviando el Name la String o estoy enviando el objeto Person completo? Aquí está el nuevo método Distinct:

public static class ExtensionMethods { public static IEnumerable<T> Distinct<T>( this IEnumerable<T> list, Func<T,object> checker) { return list.Distinct(new GenericComparer<T>(checker)); } } public class GenericComparer<T> : IEqualityComparer<T> { private Func<T, object> _checker; public GenericComparer(Func<T,object> checker) { _checker = checker; } public bool Equals(T x, T y) { return _checker(x).Equals(_checker(y)); } public int GetHashCode(T obj) { return _checker(obj).GetHashCode(); } }

Y aquí está el uso:

static void Main(string[] args) { var persons = new List<Person>() { new Person() { Id = 1, Name = "Mary"}, new Person() {Id = 2, Name="John"}, new Person() { Id = 3, Name = "Mary"} }; var uniquePersons = persons.Distinct(p => p.Name); foreach(var person in uniquePersons) { Console.WriteLine(person.Name); } }


Cuando haces esto:

persons.Distinct(p => p.Name);

Básicamente, estás creando una función sobre la marcha ( usando expresiones lambda ), que se ve así:

string theFunction(Person p) { return p.Name; }

Esta es una función que se ajusta a la firma de un delegado Func<Person,String> . El método Distinct puede tomar un delegado (básicamente un puntero de función) que utiliza para determinar si un elemento es distinto o no, en su caso, solo las cadenas únicas (devueltas por la función anterior) se considerarán elementos "distintos". Este delegado se ejecuta en cada elemento de sus "personas" enumerables, y se utilizan los resultados de esas funciones. A continuación, crea una secuencia ( IEnumerable<Person> ) a partir de esos elementos.


Usted está recuperando a las Personas distintas, bajo el supuesto de que dos Personas son iguales si tienen el mismo nombre

Si desea un conjunto distinto de nombres, puede utilizar esto:

IEnumerable<String> names = persons.Select(p => p.Name).Distinct();


Func<T, TResult>

define una función que acepta un parámetro (de tipo T) y devuelve un objeto (de tipo TResult).

En su caso, si desea una función que tome un objeto Person y devuelva una cadena ... desearía

Func<Person, string>

que es el equivalente de:

string Function(Person p) { return p.Name; }