33 votes

Delegate pour une Action<ref T1, T2>

Je suis en train de créer une déléguée d'une méthode statique qui prend un argument de référence. S'il vous plaît, ne demandez pas pourquoi je fais une telle chose loufoque. Cela fait partie de l'apprentissage de comment fonctionnent .Net, C# et la réflexion et comment l'optimiser.

Mon code est :

    public struct DataRow
    {

        private double t;
        static public void Cram_T(ref DataRow dr, double a_t)
        {
            dr.t = a_t;
        }
    }
 ''''
  Type myType = typeof(DataRow);
  MethodInfo my_Cram_T_Method = myType.GetMethod("Cram_T");
  var myCram_T_Delegate = 
         Delegate.CreateDelegate(typeof(Action),      
                                 my_Cram_T_Method) 
                                 as Action;

Cela me donne une erreur de liaison car (je pense) l'action générique ne correspond pas à la méthode.

En inspectant la valeur de Cram_T_Method dans la fenêtre de surveillance donne

{Void Cram_T(DataRow ByRef, Double)}

J'ai ensuite essayé d'utiliser le mot-clé ref dans l'Action :

  var myCram_T_Delegate = 
         Delegate.CreateDelegate(typeof(Action),         
                                 my_Cram_T_Method) 
                                 as Action;

Mais cela ne compile pas. Le compilateur C# bloque au jeton "ref".

Quelle est la bonne façon de créer cette déléguée?

46voto

Ben M Points 14458

Créez votre propre type de délégué :

délégué void MyAction(ref DataRow dataRow, double doubleValue);

Et utilisez MyAction à la place de Action -- qui, comme vous l'avez noté, ne compile pas.

28voto

Jon Skeet Points 692016

@Ben M a la bonne idée, bien que vous pourriez la rendre plus générique :

public delegate void RefAction(ref T1 arg1, T2 arg2)

Le problème n'a rien à voir avec les délégués en tant que tel - c'est juste que vous ne pouvez pas utiliser ref lorsque vous spécifiez un argument de type.

En théorie, "c'est par référence ou non" fait partie des informations de type (d'où Type.IsByRef) mais vous ne pouvez pas le spécifier de cette manière.

Franchement, je ne suis pas du tout sûr de ce qui se passerait si vous essayiez de créer une List via reflection, par exemple - je espère qu'une exception serait lancée... ce n'est pas un concept très sensé :)

EDIT: Je viens d'essayer :

Type refInt = typeof(int).MakeByRefType();
Type refIntList = typeof(List<>).MakeGenericType(refInt);

Lance une erreur :

Unhandled Exception: System.ArgumentException: Le type 'System.Int32&' ne peut pas
être utilisé en tant qu'argument de type.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X