c# - microsoft - Func vs. Acción vs. Predicado
event c# (3)
Func : cuando desea un delegado para una función que puede o no tomar parámetros y devolver un valor. El ejemplo más común sería Select from LINQ:
var result = someCollection.Select( x => new { x.Name, x.Address });
Acción : cuando desea un delegado para una función que puede o no tomar parámetros y no devuelve un valor. Los uso a menudo para manejadores de eventos anónimos:
button1.Click += (sender, e) => { /* Do Some Work */ }
Predicado : cuando desea una versión especializada de un Func que evalúa un valor según un conjunto de criterios y devuelve un resultado booleano (verdadero para una coincidencia, falso de lo contrario). Nuevamente, estos se usan en LINQ con bastante frecuencia para cosas como Dónde:
var filteredResults =
someCollection.Where(x => x.someCriteriaHolder == someCriteria);
Acabo de verificar dos veces y resulta que LINQ no usa Predicados. No estoy seguro de por qué tomaron esa decisión ... pero en teoría todavía es una situación en la que un Predicado encajaría.
Esta pregunta ya tiene una respuesta aquí:
- Delegados: Predicate Action Func 8 respuestas
Con ejemplos reales y su uso, ¿puede alguien ayudarme a comprender:
- ¿Cuándo necesitamos delegado funcional?
- ¿Cuándo necesitamos acción delegada?
- ¿Cuándo necesitamos delegados Predicados?
La acción es un delegado (puntero) a un método, que toma cero, uno o más parámetros de entrada, pero no devuelve nada.
Func es un delegado (puntero) a un método, que toma cero, uno o más parámetros de entrada y devuelve un valor (o referencia).
El predicado es un tipo especial de Func que se usa a menudo para las comparaciones.
Aunque son ampliamente utilizados con Linq, Action y Func son conceptos lógicamente independientes de Linq. C ++ ya contenía el concepto básico en forma de punteros de función escritos.
Aquí hay un pequeño ejemplo de Action y Func sin usar Linq:
class Program
{
static void Main(string[] args)
{
Action<int> myAction = new Action<int>(DoSomething);
myAction(123); // Prints out "123"
// can be also called as myAction.Invoke(123);
Func<int, double> myFunc = new Func<int, double>(CalculateSomething);
Console.WriteLine(myFunc(5)); // Prints out "2.5"
}
static void DoSomething(int i)
{
Console.WriteLine(i);
}
static double CalculateSomething(int i)
{
return (double)i/2;
}
}
La diferencia entre Func
y Action
es simplemente si desea que el delegado devuelva un valor (use Func
) o no (use Action
).
Es probable que la función se use más comúnmente en LINQ, por ejemplo en proyecciones:
list.Select(x => x.SomeProperty)
o filtrado:
list.Where(x => x.SomeValue == someOtherValue)
o selección de teclas:
list.Join(otherList, x => x.FirstKey, y => y.SecondKey, ...)
Action
se usa más comúnmente para cosas como List<T>.ForEach
: ejecuta la acción dada para cada elemento de la lista. Uso esto con menos frecuencia que Func
, aunque a veces uso la versión sin parámetros para cosas como Control.BeginInvoke
y Dispatcher.BeginInvoke
.
Predicate
es solo un Func<T, bool>
especial en Func<T, bool>
realmente introducido antes de que llegara todo el Func
y la mayoría de los delegados de Action
. Sospecho que si ya hubiéramos tenido Func
y Action
en sus diversas formas, Predicate
no se habría presentado ... aunque le da un cierto significado al uso del delegado, mientras que Func
y Action
se usan para disparidades muy diversas. fines
Predicate
se usa principalmente en la List<T>
para métodos como FindAll
y RemoveAll
.