Func frente de Acción frente Predicado [duplicate]
Esta pregunta ya tiene una respuesta aquí:
- Delegates: Predicate Action Func 8 respuestas
Con ejemplos reales y su uso, puede alguien por favor ayudarme a entender:
- ¿Cuándo necesitamos un delegado Func?
- ¿Cuándo necesitamos delegado de acción?
- ¿Cuándo necesitamos delegar Predicados?
3 answers
La diferencia entre Func
y Action
es simplemente si desea que el delegado devuelva un valor (use Func
) o no (use Action
).
Func
es probablemente más comúnmente utilizado 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
: ejecutar la acción dada para cada elemento de la lista. Uso esto con menos frecuencia que Func
, aunque hago a veces uso el versión sin parámetros para cosas como Control.BeginInvoke
y Dispatcher.BeginInvoke
.
Predicate
es solo un caso especial Func<T, bool>
realmente, presentado antes de todos los Func
y la mayoría de los Action
delegados vinieron. Sospecho que si ya hubiéramos tenido Func
y Action
en sus diversas formas, Predicate
no se habrían introducido... aunque hace impartir un cierto significado al uso del delegado, mientras que Func
y Action
se utilizan para fines muy dispares.
Predicate
se utiliza sobre todo en List<T>
para métodos como FindAll
y RemoveAll
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-14 03:55:15
Action 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 usado a menudo para comparaciones.
Aunque ampliamente utilizado con Linq, Acción 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 para 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;
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-08 21:04:16
Func - Cuando desea un delegado para una función que puede o no tomar parámetros y devuelve un valor. El ejemplo más común sería Select from LINQ:
var result = someCollection.Select( x => new { x.Name, x.Address });
Action - 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 */ }
Predicate - Cuando desea una versión especializada de un Func que evalúa un valor contra un conjunto de criterios y devuelve un resultado booleano (true para una coincidencia, false de lo contrario). Nuevamente, estos se usan en LINQ con bastante frecuencia para cosas como Where:
var filteredResults =
someCollection.Where(x => x.someCriteriaHolder == someCriteria);
Acabo de comprobar dos veces y resulta que LINQ no utiliza Predicados. No estoy seguro de por qué tomaron esa decisión...pero teóricamente todavía es una situación donde un Predicado encajaría.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-25 11:17:39