2010-04-28 4 views
3

J'essaie vraiment de suivre le principe DRY. J'ai un sous qui ressemble à ceci? Je voudrais les condenser en une seule méthode en utilisant des génériques. Pour l'enregistrement, ItemSummaries et NumberedInventories sont tous deux dérivés de la même classe de base DataBuilderBase.Comment créer une méthode générique dans une classe?

Je ne peux pas comprendre la syntaxe qui me permettra de faire ItemSumms.FillRows et numInvs.FillRows dans la méthode.

FillRows est déclaré Public Overridable Sub FillRows dans la classe de base.

Merci d'avance.

EDIT
Voici mon résultat final

Private Sub DoSupplyModels() 

    DoSupplyModelType("ITEM SUMMARIES",New DataBlocks(_currentSupplyModel,_excelRows) 
    DoSupplyModelType("DATA BLOCKS",New DataBlocks(_currentSupplyModel,_excelRows) 

End Sub 

Private Sub DoSupplyModelType(ByVal outputDescription As String, ByVal type As DataBuilderBase) 
    OutputLine(outputDescription) 
    type.FillRows() 
    OutputLine("") 
End Sub 

Mais pour répondre à ma question ... je aurais pu faire ça ...

Private Sub DoSupplyModels() 

    DoSupplyModelType(Of Projections)("ITEM SUMMARIES") 
    DoSupplyModelType(Of DataBlocks)("DATA BLOCKS") 

End Sub 

Private Sub DoSupplyModelType(Of T as DataBuilderBase)(ByVal outputDescription As String, ByVal type As T) 
    OutputLine(outputDescription) 
    Dim type as New DataBuilderBase (_currentSupplyModel,_excelRows) 
    type.FillRows() 
    OutputLine("") 
End Sub 

Est-ce exact?

Seth

+0

Est-ce qu'un C# exemple aider? – R0MANARMY

+0

Vous voulez changer DoSupplyModel pour recevoir un 'ItemSummaries' ou un' NumberedInventories'? Si c'est le cas, vous pouvez simplement utiliser la classe de base 'DataBuilderBase' pour recevoir le type de paramètre. Vous n'avez pas besoin d'un générique dans ce cas. –

+0

C# est bien ... Je peux le convertir si je ne comprends pas ... mais je lis assez bien C#. –

Répondre

3

Comme d'autres l'ont souligné, vous n'avez pas besoin de génériques pour faire ce que vous voulez, mais je vais répondre à la question d'ordre technique complet:

Private Sub MyMethod(Of T As DataBuilderBase)(ByVal instance As T) 
    instance.FillRows() 
End Sub 

Et puis appeler la méthode en faisant ceci:

MyMethod(Of ItemSummaries)(new SupplyModel.ItemSummaries(...)) 
+0

Merci d'avoir répondu à la question dans la bonne langue. – R0MANARMY

1

vous pouvez factoriser pour tirer profit du fait que la part d'une base commune et polymorphisme utilisation: (VB un peu rouillé, vous devriez obtenir l'idée)

vous pourriez avoir une méthode:

Private Sub FillAndOutput(textToOutput as String, filler as DataBuilderBase) 
    OutputLine(string)   
    filler.FillRows() 
    OutputLine("") 
end sub 

que vous pouvez appeler:

Private Sub DoSupplyModel 
    FillAndOutput("ITEM SUMMARIES",New SupplyModel.ItemSummaries(_currentSupplyModel, _excelRows)) 
    FillAndOutput("NUMBERED INVENTORIES",New SupplyModel.NumberedInventories(_currentSupplyModel, _excelRows))   

End Sub 
+0

Je pense que c'est déjà vrai ** FillRows est déclaré comme Public Overridable Sub FillRows dans la classe de base. ** – R0MANARMY

+0

ahh merci, édité les exemples pour refléter cela –

1

Fondamentalement vous devez spécifier que T sera une sous-classe du type de base qui implémente la méthode FillRows. En C# cela ressemblerait si

private void myFunction<T>(T someList) where T : DataBuilderBase { 
    someList.FillRows(); 
} 

trouvé un VB.NET example on MSDN.

EDIT et Kevin a raison, cela serait probablement mieux géré avec le polymorphisme.

+0

C'est là où T: DataBuilderBase que je n'ai pas compris comment faire. (En d'autres termes, comment contraindre le type générique.) Dans VB, la syntaxe est Private myFunction (Of T As DataBuilderBase) (ByVal someList As T). MERCI UN MILLIARD. –

0

Dans ce cas, je ne pense pas que le refactoring à une fonction générique soit justifiable, même au prix de se répéter. Vous avez deux options:

  1. refactoring votre code de manière à permettre aux constructeurs de créer une et sans paramètre fonction à un niveau plus élevé de l'héritage qui vous permet de spécifier les arguments actuellement passés au constructeur.
  2. Utilisez une réflexion explicite pour instancier le type générique et passez ces arguments au constructeur.

L'une ou l'autre de ces options implique une quantité de travail non triviale avec très peu de gain (vous traduisez trois lignes de code en une seule).

Cependant, pour répondre à votre question, VB.NET utilise le mot-clé of pour spécifier des arguments de type générique

Public Sub Foo(Of T)(argument as T) 
    ... 
End Sub 
+0

Je suis curieux de savoir pourquoi vous ne pensez pas que cela soit justifiable? Seth –

+0

@Seth: Le coût de rendre générique est trop élevé par rapport aux avantages que vous verrez. La seule raison pour laquelle vous auriez besoin de le rendre générique serait soit d'instancier le type générique (ce qui signifierait que vous auriez à passer par le problème que j'ai énuméré dans mon anwer) ou de retourner le type générique afin que vous puissiez avoir un interface plus fluide (je ne vois pas vraiment cela étant le cas). La seule partie qui pourrait être refactored dehors de ceux-ci est l'appel à 'FillRows', et je ne vois tout simplement pas l'avantage de créer une nouvelle fonction qui appelle simplement une autre fonction sans logique. –

Questions connexes