2010-11-25 37 views
2

S'il vous plaît noter que je ne parle pas générique Type paramètres.Pourquoi n'y a-t-il pas d'équivalent dans les paramètres génériques C# à Ada?

Par exemple, dans Ada, je peux écrire un paquet qui doit être initialisé en utilisant une valeur au lieu d'un type. par exemple.

generic 
    Size : Positive; 
package Sudokus is 

    subtype Values is Positive range 1..Size*Size; 
    type Choice is private; 
    type Sudoku is private; 

    procedure Fill(S : out Sudoku); 
    procedure Init(S : out Sudoku); 
    procedure Solve(S : in out Sudoku); 
    procedure Print(S : Sudoku); 

    Unsolvable_Grid_Error : exception; 

Et voici comment l'utiliser:

package My_Sudoku is new Sudokus(3); -- 3 for 9x9 solver, 4 for 16x16 solver, etc. 

Je suppose qu'il n'y a pas d'équivalent mais je trouve cela très utile. Y a-t-il une raison à cette absence?

+9

N'est-ce pas quelque chose que vous pouvez généralement transmettre à un constructeur? – Rup

+3

Pourriez-vous fournir un exemple qui ne pourrait pas être facilement résolu par un appel de constructeur? –

+0

Un vecteur struct. Mais celui-ci est probablement mieux avec une seule fois pour chaque dimension de 2 à 4. – CodesInChaos

Répondre

3

La réponse générale à la question «pourquoi C# n'a pas la caractéristique X» tourne autour des avantages d'une telle caractéristique par rapport aux coûts. Les avantages sont généralement évidents, mais les coûts comprennent:

  • complexité accrue des spécifications du langage
  • La complexité croissante du code en utilisant la langue à la pleine
  • accrue exigence pédagogique - les développeurs doivent en savoir plus afin de comprendre leur Code de collègues
  • Coût de la conception de la fonction
  • le coût de la mise en œuvre de la fonction
  • coût des tests de la fonction
  • La difficulté accrue à ajouter plus de fonctionnalités plus tard - parce que souvent les caractéristiques vont interagir les uns avec les autres, souvent de façon maladroite

Fondamentalement, il ne devrait pas être un cas de demande pourquoi une caractéristique particulière n'est pas présent: il devrait être une question de faire valoir que les avantages de la fonctionnalité sont énormes par rapport aux coûts. Les fonctionnalités doivent gagner leur place dans la langue, et les concepteurs de la langue ont placé la barre très haut. (Comme Anders l'a dit dans le passé, chaque fonctionnalité commence avec un score de -100, et doit progresser.)

1

Pourquoi ne pas simplement passer la taille au constructeur et initialiser le tableau avec ça?

class Sudokus 
{ 
    char[] field; 
    public Sudokus (int size){ field = new char[size*size]; } 
} 

L'avantage que je pouvais voir avec un « paramètre générique » est si vous aviez un tableau de taille fixe, ce qui pourrait permettre un accès plus rapide, mais qui ne sont pas pris en charge en C# de toute façon (au moins pas non -variable locale).

Je sais que ce type de modèle est supporté en C++, ce qui est bien supérieur à la modélisation en C# ou en Java.

+3

Les génériques C# ne sont pas conçus pour commencer, et ne devraient pas être considérés de cette façon.La supériorité dépend du contexte - dans certains cas, les modèles C++ sont plus utiles, et ils sont * généralement * plus puissants; Dans d'autres situations, les génériques C# sont tout aussi utiles et plus simples à comprendre. Dans certains cas, les génériques C# fournissent des capacités qui, pour autant que je sache, ne sont pas disponibles avec les modèles C++, comme la création du type générique lorsque l'argument type est uniquement connu au moment de l'exécution. La possibilité de fournir des génériques uniquement sous forme binaire est également potentiellement utile. –

+0

@Jon: vous avez raison. Bien qu'il soit tout à fait possible de * instancier * des types de template en C++ - à peu près équivalents à la contrainte 'new' en C# - ceci est toujours résolu à la compilation et il n'y a vraiment pas d'équivalent à Activator.CreateInstance) 'se résout à. –

+0

@Konrad: Je voulais plus dire l'équivalent de l'utilisation de la réflexion pour créer une 'Liste ' où 'T' n'est connu qu'à l'exécution, par exemple. (En utilisant 'Type.MakeGenericType'.) –