Je ne suis pas sûr que cela soit possible ou non.
J'ai un certain nombre de classes différentes qui implémentent l'interface IBAR et ont des constructeurs qui prennent quelques valeurs. Plutôt que de créer un tas de méthode presque identique, est-il possible d'avoir une méthode générique qui créera le constructeur approprié? p> i get: p>
3 Réponses :
Malheureusement pas - Les génériques .NET ne vous permettent que de contraindre un type générique pour avoir un constructeur sans paramètre, que vous pouvez ensuite appeler avec Si cela ne vous dérange pas de faire de vos types mutable, vous pouvez créer une interface qui contenant une méthode em> avec les paramètres pertinents, permettez à tous vos types d'implémenter l'interface, puis contraignez le type à mettre en œuvre. cette méthode et avoir un constructeur sans paramètre, mais ce n'est pas idéal. P>
Une autre option consiste à transmettre dans un nouveau t () code> ... Vous ne pouvez pas spécifier un particulier ensemble de paramètres. p>
approprié> Func code> qui prend
x code> et
p1 code> et renvoie un nouveau
t code> chaque fois. Cela serait certainement facile à utiliser à partir de C # - pas tout à fait em> si facile dans la VB IIRC, mais la peine d'être envisagée néanmoins. P>
FUNC CODE> est OK maintenant dans vb.net. C'est encore plus verbeux qu'en C # cependant.
@Toddmo: Cela fonctionnera si vous contraindrez le type générique à avoir un constructeur sans paramètre i>. Cela ne fonctionnera pas si vous n'avez pas cette contrainte.
@Jonskeet, si vous aviez écrit Sub FOO (de T comme {myClass, nouveau}) code> Pour montrer ce que vous vouliez dire, je n'aurais pas été confus. Vous avez dit quelque chose mais ne l'a pas illustré. Merci.
En ce qui concerne la première option que vous avez mentionnée: suggérez-vous de créer l'objet via un constructeur sans paramètre, puis exécutez ensuite une fonction code> qui ferait le travail censé être fait à l'intérieur du constructeur complet de paramètres d'origine ? En d'autres termes, quelque chose comme
getfoo (de T comme ibar) (P1, P2): ...: DIM Barre en tant que nouveau t: bar.finishConstruction (x, p1) code> (où
finalconstruction code> fait partie de
ibar code>, qui est implémenté par
bar code>)?
Développement de la réponse de Jon Skeet, voici une solution possible à l'aide d'un paramètre code> Func code>: utilisation serait similaire à p>
Lorsque j'essaie de créer une fonction barimpl (i, o) comme foo {retournez nouvelle foo (i, o)}, alors je reçois une erreur lorsque vous appelez getfoo qui dit Barimpl n'est pas défini.
Barimpl code> est une classe implémentant
ibar code>, pas une fonction
code>
C'est une idée brillante d'utiliser des méthodes d'usine. Il est probablement préférable des constructeurs aussi une fois qu'il est en place, car vous pourriez penser comme injecter un état dans votre méthode de construction que vous ne pouvez pas faire dans le véritable constructeur.
Il est possible de cal, un constructeur même s'il n'est pas spécifié dans des contraintes génériques. Voir l'exemple ci-dessous.
'This base class has no constructor except the default empty one Public Class MyBaseClass End Class 'this class inhetits MyBaseType, but it also implements a non empty constructor Public Class MySpecializedClass Inherits MyBaseClass Public Sub New(argument As String) End Sub End Class Public Function CreateObject(Of ClassType As MyBaseClass)(argument As String) As ClassType 'First, get the item type: Dim itemType As Type = GetType(ClassType) 'Now we can use the desired constructor: Dim constructor As ConstructorInfo = itemType.GetConstructor(New Type() {GetType(String)}) If constructor Is Nothing Then Throw New InvalidConstraintException("Constructor ""New(String)"" not found.") Else Dim result As ClassType = constructor.Invoke(New Object() {argument}) Return result End If End Function Public Sub RunTest() Try Console.WriteLine("+----------------------------------------------------+") Console.WriteLine("Trying to create a instance of MyBaseClass") Console.WriteLine("+----------------------------------------------------+") Dim myobject As MyBaseClass = CreateObject(Of MyBaseClass)("string value") Console.WriteLine(myobject) Console.WriteLine("Instance of MyBaseClass created") Catch ex As Exception Console.WriteLine(ex) End Try Try Console.WriteLine("+----------------------------------------------------+") Console.WriteLine("Trying to create a instance of MySpecializedClass") Console.WriteLine("+----------------------------------------------------+") Dim myobject As MyBaseClass = CreateObject(Of MySpecializedClass)("string value") Console.WriteLine(myobject) Console.WriteLine("Instance of MySpecializedClass created") Catch ex As Exception Console.WriteLine(ex) End Try End Sub
Intéressant d'utiliser la réflexion. Mon constructeur implique une interface; Je ne sais pas comment le gettype (t) .getConstructor (nouveau type () {itheinterface}) code> se passe pour gérer cela, mais je suis optimiste!