con ejemplos reales y su uso, por favor alguien puede ayudarme a entender:Func vs Acción contra predicado
- ¿Cuándo necesitamos Func delegado?
- ¿Cuándo necesitamos la acción delegar?
- ¿Cuándo necesitamos un delegado de Predicados?
con ejemplos reales y su uso, por favor alguien puede ayudarme a entender:Func vs Acción contra predicado
La diferencia entre Func
y Action
es simplemente si desea que el delegado para regresar un valor (use Func
) o no (utilizar Action
).
Func
es probablemente el más comúnmente utilizado en LINQ - por ejemplo, en las proyecciones:
list.Select(x => x.SomeProperty)
o filtrado:
list.Where(x => x.SomeValue == someOtherValue)
o tecla de selección:
list.Join(otherList, x => x.FirstKey, y => y.SecondKey, ...)
Action
es más comúnmente utilizado para cosas como : ejecutar el dar n acción para cada elemento en la lista. Lo uso con menos frecuencia que Func
, aunque I do a veces usa la versión sin parámetros para cosas como Control.BeginInvoke
y Dispatcher.BeginInvoke
.
Predicate
es realmente una carcasa especial Func<T, bool>
realmente, presentada antes de todos los Func
y la mayoría de los delegados Action
llegaron. Sospecho que si ya habíamos tenido Func
y Action
en sus diversas formas, Predicate
no se hubieran introducido ... aunque no impartir un cierto significado para el uso del delegado, mientras que Func
y Action
se utilizan para propósitos ampliamente dispares.
Predicate
se utiliza principalmente en List<T>
para métodos como FindAll
y RemoveAll
.
Me gusta mucho ver 'Predicado' en una firma de función. Ilustra que el método pasado toma una decisión en lugar de solo devolver un código de éxito o un tipo diferente de 'bool'. –
¿Hay alguna directriz de diseño sobre si prefiere 'Predicado
@Ron: Sí, de eso se trata mi penúltimo párrafo. –
Func - Cuando quiere 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 Seleccionar de LINQ:
var result = someCollection.Select(x => new { x.Name, x.Address });
Acción - Cuando se desea un delegado para una función que pueden o no tener parámetros y no devuelve un valor. Yo uso estos a menudo para los controladores de eventos anónimos:
button1.Click += (sender, e) => { /* Do Some Work */ }
predicado - Cuando se desea una versión especializada de un Func que toma evalúa un valor contra un conjunto de criterios y devuelve un resultado booleano (verdadero para un partido, falso de lo contrario).
Una vez más, estos se utilizan en LINQ con bastante frecuencia para cosas como Dónde:
var filteredResults =
someCollection.Where(x => x.someCriteriaHolder == someCriteria);
acabo comprobados con minuciosidad y resulta que LINQ no utiliza predicados. No estoy seguro de por qué tomaron esa decisión ... pero, en teoría, todavía es una situación en la que cabría un Predicado.
Sé que esto es antiguo, pero LINK no utilizó Predicate porque es anterior al Func y a la Acción que conocemos hoy, y los dos últimos se pueden usar para obtener exactamente el mismo resultado de una manera mucho mejor. – gparent
@gparent, ¿por qué es mejor? Creo que la legibilidad es mejor cuando se usan delegados con nombres significativos en lugar de 'Func' o' Action'. – Sam
Depende de cómo use los delegados, pero a veces el nombre no es tan importante y tener que crear funciones y variables para un solo uso me disminuye la legibilidad. – gparent
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).
Predicado es un tipo especial de Func de uso frecuente para las comparaciones.
Aunque ampliamente utilizado 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 tipeados.
Aquí hay un pequeño ejemplo para la Acción y Func sin utilizar 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;
}
}
pesar de que este es un duplicado tiene una respuesta aceptada más a fondo – reggaeguitar
@reggaeguitar Lo que es interesante es que tanto de la respuesta aceptada es de Jon Skeet – rafid059