Générique de constructeurs et de réflexion
Est-il possible de voir quel constructeur a été le générique?
internal class Foo<T>
{
public Foo( T value ) {}
public Foo( string value ) {}
}
var constructors = typeof( Foo<string> ).GetConstructors();
La propriété 'ContainsGenericParameters' me renvoie pour les deux constructeurs faux. Est-il un moyen pour savoir que les constructeurs[0] est le générique? Ils ont tous deux la même signature, mais je tiens à appeler le "réel" de la chaîne.
EDIT:
Je voudrais invoquer le type donné à l'aide de
ilGen.Emit( OpCodes.Newobj, constructorInfo );
donc j'ai besoin de travailler avec la limite de la version. Mais je tiens à appeler le "meilleur" du constructeur. Que devrait être le comportement normal. Quand je l'appelle
new Foo<string>()
le constructeur avec la chaîne de signature (et non pas l'un avec le générique de la signature) est appelée. La même chose devrait se produire avec mon code.
OriginalL'auteur tanascius | 2009-05-15
Vous devez vous connecter pour publier un commentaire.
Vous souhaitez Système.De la réflexion.ParameterInfo.ParameterType.IsGenericParameter. Voici un VS2008 de test de l'unité qui passe qui illustre cela:
Classe:
Méthode d'essai:
Le point notable ici, c'est le parms[0].ParameterType.IsGenericParameter vérifier qui vérifie si le paramètre est un générique ou non.
Une fois que vous avez trouvé votre constructeur alors vous avez la ConstructorInfo de passer à Émettre.
Pas exactement sûr de ce que votre intention est bien.
appel GetGenericTypeDefinition() pour l'obtenir sur le Foo<> alors que le constructeur indices encore la carte de la même constructeur. Ainsi, vous pouvez réfléchir sur Foo<>..ctor pour trouver le bon indice ensuite utiliser le correspondant Foo<string>..ctor à votre IL du générateur. Aussi loin que je peux vous dire perdre tout générique ness quand vous allez avec Foo<string>.
GetGenericTypeDefinition() est exactement ce que j'ai raté. Merci beaucoup!
Btw. joli style pour répondre à cette question avec un travail unittest!
OriginalL'auteur Colin Burnett
Léger éclaircissement. Ni les constructeurs sont des méthodes génériques. Ils sont normaux méthodes d'une classe générique. Pour une méthode de "générique", il doit avoir un paramètre générique . Donc en faisant un test, comme "IsGenericMethod" retourne la valeur false.
C'est pas facile de simplement regarder les paramètres et de déterminer si elles sont génériques. Pour l'exemple que vous avez donné, il est possible de marcher dans les arguments et recherchez un paramètre générique. Mais également d'étudier le code suivant
Vous aurez besoin de prendre des articles comme cela en compte.
MODIFIER
La raison pour laquelle vous voyez tous les arguments de la chaîne est parce que vous l'avez explicitement lié au type Foo avant d'obtenir les constructeurs. Essayez de faire passer votre code de la manière suivante, qui utilise un indépendant Foo et donc sera de retour générique paramètres dans les méthodes.
juste mis à jour ma réponse pour expliquer le problème
merci pour votre explication et de clarification. Je sais, qu'il travaille avec typeof( Foo<> ) ... alors je vous comprends bien, que, après le rattachement à la chaîne de la réflexion ne m'aidera pas plus?
OriginalL'auteur JaredPar
Vous pouvez cocher la case Type.GetGenericArguments type de résultat(s), et le comparer avec le paramètre du constructeur de type.
Il suffit d'appeler l'un avec un type qui n'est pas le même (de type != typeof(T)).
ni est générique parce que vous avez fermé le type en fournissant chaîne comme argument de type. utiliser typeof(Foo<>) à la place.
OriginalL'auteur Reed Copsey
Pouvez-vous expliquer un peu plus ce que vous essayez d'accomplir, quand vous dites que vous voulez l'appeler le constructeur en béton? Je suis juste curieux de savoir si il y a une autre façon de résoudre votre problème sans avoir à détecter si le constructeur contient les paramètres génériques.
Je pense chaînage des constructeurs ou des bâtiment de logique dans le générique de se comporter d'une certaine façon, si le paramètre passé dans une chaîne de caractères, tels que:
Une autre option serait de créer une mise en œuvre concrète de Toto, quelque chose comme:
et intégrer la logique spécifique dans le constructeur de la descendant. Toutes sortes d'options en bas de ce chemin sont possibles afin que vous pouvez éviter d'avoir à refléter l'info de chaque classe.
OriginalL'auteur nkirkes