2010-06-14 5 views
2

Je suis nouveau sur Stack Overflow, alors pardonnez-moi. Je viens juste de commencer à passer en C# et je suis coincé sur un problème. Je souhaite transmettre une classe générique et appeler une méthode de cette classe. Donc, mon code ressemble en tant que tel:.NET 2.0: Invoquer des méthodes utilisant la réflexion et les génériques provoque une exception

public void UpdateRecords<T>(T sender) where T : new() //where T: new() came from Resharper 
{ 
    Type foo = Type.GetType(sender.GetType().ToString()); 
    object[] userParameters = new object[2]; 
    userParameters[0] = x; 
    userParameters[1] = y; 
    sender = new T(); //This was to see if I could solve my exception problem 
    MethodInfo populateRecord = foo.GetMethod("MethodInOtherClass"); 
    populateMethod.Invoke(sender, userParameters); 
} 

Exception levée: « référence d'objet non définie à une instance d'un objet. »

Encore une fois, je m'excuse vraiment, car je suis presque nouveau à C# et c'est la première fois que j'ai manipulé la réflexion et les génériques. Je vous remercie!

+3

Où exactement est levée l'exception? – Femaref

Répondre

6

Tout d'abord, je vous recommande d'utiliser ce code dans le débogueur et en tournant un « Break on Exception " pour aider à isoler quelle ligne provoque l'erreur. C'est une technique de débogage utile qui peut vous aider à trouver ces types de problèmes plus rapidement dans le futur. Passez à Debug >> Exceptions dans VS et cochez la case Common Language Runtime Exceptions dans la colonne Thrown.

Maintenant pour votre problème. Il est probable que sender est passé en tant que null. Si oui, la ligne:

Type foo = Type.GetType(sender.GetType().ToString()); 

lancera une NullReferenceException. Au lieu de cela, vous pouvez utiliser:

Type foo = typeof(T); 

qui identifie le type du paramètre générique sans nécessiter une instance de celui-ci. Maintenant, sans en savoir plus sur ce que votre code essaie de faire, il est impossible de dire si l'instanciation d'une instance de T est la bonne chose à faire. Tout simplement parce que ReSharper recommande d'ajouter where T : new() ne veut pas dire qu'il est approprié - sauf vous savez que c'est le bon comportement.Enfin, je ne sais pas s'il y a une raison impérieuse d'utiliser la réflexion pour appeler MethodInOtherClass - peut-être qu'il y en a. Mais puisque vous êtes nouveau à C#, je mentionnerai que si le type T sera toujours une sous-classe d'un type de base A ou implémentera toujours une interface I qui inclut la méthode que vous voulez appeler, vous pouvez simplement appliquer un générique contrainte de laisser le compilateur le savoir. Ensuite, vous pouvez appeler la méthode sans utiliser la réflexion:

Beaucoup plus agréable.

Un dernier commentaire. Il est inhabituel de passer un argument à une méthode, puis de l'ignorer complètement - seulement pour instancier une instance dans la méthode. Il y a des cas où c'est approprié - mais j'ai tendance à le voir comme code smell. Si possible, je voudrais essayer soit de se débarrasser de l'argument sender, soit changer le code pour le tester d'abord pour null et instancier seulement alors.

1

Vous devez simplement être en mesure de le faire pour obtenir le type:

Type foo = typeof(T); 

Vous n'avez pas spécifié où vous obtenez le NullReferenceException, mais je me demande si foo revient comme nulle. ..

2

sender.GetType().ToString() renvoie le nom de type sans le nom de l'assembly.

Type.GetType attend un nom de type avec un nom d'assembly (sauf si le type est dans l'assembly d'exécution ou mscorlib). Si le type ne peut pas être trouvé (par exemple, en raison du nom d'assembly manquant), il renvoie une référence null.


Essayez de changer votre code à

Type foo = sender.GetType(); 

ou même

Type foo = typeof(T); 
0

Soit:

  1. sender est nulle, donc sender.GetType() échouera.
  2. foo.GetMethod("MethodInOtherClass") renvoie null, donc populateMethod.Invoke() échouera.
  3. MethodInOtherClass dépend de certaines conditions préalables (références non nulles), il échouera donc lorsque ceux-ci sont absents.
Questions connexes