Wszyscy delegaci Func zwracają wartość. Jakich delegatów .NET można używać z metodami, które zwracają wartość void?
Wszyscy delegaci Func zwracają wartość. Jakich delegatów .NET można używać z metodami, które zwracają wartość void?
Odpowiedzi:
Wszyscy delegaci Func zwracają coś; wszyscy delegaci akcji zwracają nieważność.
Func<TResult>
nie przyjmuje argumentów i zwraca TResult:
public delegate TResult Func<TResult>()
Action<T>
pobiera jeden argument i nie zwraca wartości:
public delegate void Action<T>(T obj)
Action
jest najprostszym „nagim” delegatem:
public delegate void Action()
Są też Func<TArg1, TResult>
i Action<TArg1, TArg2>
(i inne do 16 argumentów). Wszystkie te (z wyjątkiem Action<T>
) są nowe w .NET 3.5 (zdefiniowane w System.Core).
Func<,,, ... ,>
) w .NET 4.0, ale ostatnie osiem typów każdej „serii” jest zdefiniowane w System.Core.dll
, a nie w mscorlib.dll
, więc to byłby powód dlaczego Michielvoo ich nie widział. Jednak w wersjach .NET 4.5 i 4.5.1 nie dodano żadnych funcs ani akcji. Czy ta sekwencja stanie się A170836 lub A170875 ? Bądźcie czujni.
... nie przyjmuje argumentów i ma typ nieważnego zwrotu?
Uważam, że Action
jest to rozwiązanie.
Wszyscy delegaci Func biorą co najmniej jeden parametr
To nieprawda. Wszystkie pobierają co najmniej jeden argument typu, ale ten argument określa typ zwracany.
Dlatego Func<T>
nie przyjmuje żadnych parametrów i zwraca wartość. Użyj Action
lub, Action<T>
gdy nie chcesz zwracać wartości.
Spróbuj System.Func<T>
iSystem.Action
Converter<TInput, TOutput>
który był podobny do późniejszego Func<T, TResult>
. Został użyty w List<>.ConvertAll
metodzie, która rzutowała każdy element List<>
na inny obiekt i umieściła wszystkie „wartości funkcji” w nowym List<>
. (Później często używa się Select
do tego Linq .)
Czasami będziesz chciał napisać delegata do obsługi zdarzeń, w którym to przypadku możesz skorzystać, System.EvenHandler<T>
który domyślnie akceptuje argument typu object
oprócz drugiego parametru, który powinien pochodzić EventArgs
. EventHandlers powrócąvoid
Osobiście uznałem to za przydatne podczas testowania do utworzenia jednorazowego wywołania zwrotnego w ciele funkcji.
... nie przyjmuje argumentów i ma typ nieważnego zwrotu?
Jeśli piszesz System.Windows.Forms
, możesz również użyć:
public delegate void MethodInvoker()
Bardzo łatwy sposób na wywołanie podprogramów wartości zwracanej i wartości nie zwracającej. używa odpowiednio Func i Action . (patrz także https://msdn.microsoft.com/en-us/library/018hxwa8(v=vs.110).aspx )
Wypróbuj ten przykład
using System;
public class Program
{
private Func<string,string> FunctionPTR = null;
private Func<string,string, string> FunctionPTR1 = null;
private Action<object> ProcedurePTR = null;
private string Display(string message)
{
Console.WriteLine(message);
return null;
}
private string Display(string message1,string message2)
{
Console.WriteLine(message1);
Console.WriteLine(message2);
return null;
}
public void ObjectProcess(object param)
{
if (param == null)
{
throw new ArgumentNullException("Parameter is null or missing");
}
else
{
Console.WriteLine("Object is valid");
}
}
public void Main(string[] args)
{
FunctionPTR = Display;
FunctionPTR1= Display;
ProcedurePTR = ObjectProcess;
FunctionPTR("Welcome to function pointer sample.");
FunctionPTR1("Welcome","This is function pointer sample");
ProcedurePTR(new object());
}
}