2010-01-08 3 views
25

J'essaie de créer un délégué d'une méthode statique qui prend un argument ref. S'il te plait, ne demande pas pourquoi je fais une telle chose de cockamamie. Tout cela fait partie de l'apprentissage du fonctionnement de .Net, C# et de la réflexion et comment l'optimiser.Déléguer pour une action < ref T1, T2>

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<DataRow, Double>),  
           my_Cram_T_Method) 
           as Action<DataRow, Double>; 

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

la valeur de Contrôle Cram_T_Method dans la fenêtre de la montre donne

{Void Cram_T(DataRow ByRef, Double)} 

Je puis essayé d'utiliser le mot-clé ref dans l'action:

var myCram_T_Delegate = 
     Delegate.CreateDelegate(typeof(Action<ref DataRow, Double>),   
           my_Cram_T_Method) 
           as Action<ref DataRow, Double>; 

Mais cela ne compilera pas. Le compilateur C# étouffe au jeton "ref".

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

Répondre

33

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

delegate void MyAction(ref DataRow dataRow, double doubleValue); 

et l'utilisation MyAction en place de Action<ref DataRow, Double> - qui, comme vous l'avez dit, ne compile pas.

+0

qui apporte des limites à la méthode intérieure s. – Bitterblue

21

@Ben M a la bonne idée, même si vous pouvez le rendre plus générique:

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

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

En théorie le "c'est par ref ou non" fait partie des informations de type (donc Type.IsByRef) mais vous ne pouvez pas le spécifier comme ça.

Franchement, je ne suis pas sûr du tout ce qui se passerait si vous avez essayé de créer un List<ref int> par réflexion, par exemple - je espoir qu'une exception serait jeté ... ce n'est pas un concept très raisonnable :)

EDIT: Je l'ai juste essayé:

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

génère une erreur:

Unhandled Exception: System.ArgumentException: The type 'System.Int32&' may 
not be used as a type argument. 
+4

Les arguments de type doivent être des types dont les valeurs sont convertibles en objet. Les types de pointeurs gérés et non gérés ne répondent pas à cette exigence. –

+1

Eh bien, je n'ai jamais. Fascinant. Pour une fois, je ne pense pas que ça vaudra la peine d'inclure ça dans C# in Depth. Peut-être comme une note ... –

+0

Cela fonctionne mais le commentaire de la liste est hors de propos. délégué public vide RefGenAction (réf T1 arg1, T2 arg2); var myCram_TDelegate = Delegate.CreateDelegate (typeof (RefGenAction ), myType.GetMethod ("Cram_T")) en tant que RefGenAction ; –

Questions connexes