Délégué Func sans type de retour

561

Tous les délégués Func renvoient une valeur. Quels sont les délégués .NET qui peuvent être utilisés avec des méthodes qui renvoient void?

Marcel Lamothe
la source

Réponses:

760

Tous les délégués Func retournent quelque chose; tous les délégués à l'action reviennent nuls.

Func<TResult> ne prend aucun argument et retourne TResult:

public delegate TResult Func<TResult>()

Action<T> prend un argument et ne renvoie pas de valeur:

public delegate void Action<T>(T obj)

Action est le délégué le plus simple et «nu»:

public delegate void Action()

Il y a aussi Func<TArg1, TResult>et Action<TArg1, TArg2>(et d'autres jusqu'à 16 arguments). Tous ces éléments (à l'exception de Action<T>) sont nouveaux pour .NET 3.5 (définis dans System.Core).

Jason
la source
11
Pour info, la prochaine version de la bibliothèque de classes de base comprendra des types Func et Action qui prennent en charge plus de quatre paramètres formels. Je ne me souviens pas exactement de leur taille.
Eric Lippert
88
Dans .NET 4.0, ils vont maintenant jusqu'à 8 paramètres. S'ils continuent comme ça, alors dans la prochaine version ça va aller jusqu'à onze !! 11 !!!
Michiel van Oosterhout
9
En fait, on dirait qu'ils vont jusqu'à 16 en 4.0.
Tustin2121
7
1, 4, 16, 64, 256, 1024, 4096, 16384, 65536, ... cela indique clairement que le compilateur devra être capable de gérer plus d'arguments pour une fonction qu'il n'en a actuellement à un moment donné dans le futur !
Chris Morgan
6
En fait, Tustin2121 a raison, ils sont allés jusqu'à 16 paramètres (plus un type de retour dans le cas de Func<,,, ... ,>) dans .NET 4.0, mais les huit derniers types de chaque "série" sont définis dans System.Core.dll, pas dans mscorlib.dll, donc ce serait la raison pourquoi michielvoo ne les a pas vus. Cependant, plus de Funcs ou d'actions n'ont été ajoutés dans les versions .NET 4.5 et 4.5.1. Cette séquence deviendra-t-elle A170836 ou A170875 ? Restez à l'écoute.
Jeppe Stig Nielsen
83

... ne prend aucun argument et a un type de retour vide?

Je crois que Actionc'est une solution à cela.

Marcel Lamothe
la source
48

Tous les délégués Func prennent au moins un paramètre

Ce n'est pas vrai. Ils prennent tous au moins un argument de type, mais cet argument détermine le type de retour.

Func<T>N'accepte donc aucun paramètre et renvoie une valeur. Utilisez Actionou Action<T>lorsque vous ne souhaitez pas renvoyer de valeur.

Joel Coehoorn
la source
27

Essayez System.Func<T>etSystem.Action

JaredPar
la source
1
Je ne pense pas que l'argument 0 et ainsi de suite existent dans .Net 2.0, cependant.
Brian
1
C'est bizarre: Func n'existe pas du tout dans .Net 2.0, bien que Predicate et Action existent.
Joel Coehoorn
2
Pour .NET 2.0, utilisez le délégué MethodInvoker.
Trevor Elliott, le
.NET 2 avait également (ou a) un type délégué Converter<TInput, TOutput>qui était comme le dernier Func<T, TResult>. Il a été utilisé dans la List<>.ConvertAllméthode qui projetait chaque élément d'un dans un List<>autre objet et plaçait toutes les "valeurs de fonction" dans un nouveau List<>. (Plus tard, on utilise souvent Linq Selectpour cela.)
Jeppe Stig Nielsen
0

Parfois, vous souhaiterez écrire un délégué pour la gestion des événements, auquel cas vous pouvez profiter de System.EvenHandler<T>ce qui accepte implicitement un argument de type objecten plus du deuxième paramètre qui doit dériver EventArgs. EventHandlers reviendravoid

Personnellement, j'ai trouvé cela utile lors des tests de création d'un rappel unique dans un corps de fonction.

AndyG
la source
0

... ne prend aucun argument et a un type de retour vide?

Si vous écrivez pour System.Windows.Forms, vous pouvez également utiliser:

public delegate void MethodInvoker()
mojmir.novak
la source
0

Un moyen très simple d'appeler des sous-programmes de valeur de retour et de non-retour. utilise respectivement Func et Action . (voir également https://msdn.microsoft.com/en-us/library/018hxwa8(v=vs.110).aspx )

Essayez cet exemple

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());
    }  
}
Aarón Ibañez Werthermänn
la source
1
Merci pour cet extrait de code, qui pourrait fournir une aide immédiate limitée. Une explication appropriée améliorerait considérablement sa valeur à long terme en montrant pourquoi c'est une bonne solution au problème, et la rendrait plus utile aux futurs lecteurs avec d'autres questions similaires. Veuillez modifier votre réponse pour ajouter des explications, y compris les hypothèses que vous avez faites.
iBug