2010-06-20 5 views
1

Je voudrais construire une classe générique que je peux utiliser pour implémenter des propriétés paramétrées en C#. Le code de base que je veux est la suivante:Classe de propriété paramétrée C# implémentée via Generics?

public class ParameterizedProperty<typeReturn, typeIndexer> { 
    private typeReturn oReturn = default(typeReturn); 

    public typeReturn this[typeIndexer oIndexer] { 
     get { return oReturn[oIndexer]; } 
     set { oReturn[oIndexer] = value; } 
    } 
} 

Mais depuis typeReturn est le compilateur est inconnu/sans restriction plotzing sur les lignes oReturn[oIndexer].

Alors, comment puis-je faire fonctionner cela? Ma première (bien, deuxième) pensée est d'utiliser Reflection afin de trouver conditionnellement l'indexeur (et d'élever une erreur si on n'en trouve pas) ou peut-être utiliser le modificateur where typeReturn: I??? sur la définition de classe. Mais si j'utilise le modificateur, que serait I????

Merci pour toutes les solutions à ce problème!

REMARQUE: La façon de trouver l'indexeur correctement via Reflection est (supposément) trouvée ici: http://www.dotnet247.com/247reference/msgs/3/16665.aspx (voir le dernier message). Comme Matthew a souligné ci-dessous ... J'ai quelque chose d'une faute de frappe/bug dans la description originale ... Ma propre faute, vraiment ... à l'origine l'écriture juste avant de se coucher! Le code que je veux ressemblerait plus à ceci:

public class ParameterizedProperty<typeReturn, typeIndexer> { 
    private typeReturn[] oReturn; 

    public ParameterizedProperty(typeReturn[] oSource) { 
     oReturn = oSource; 
    } 

    public typeReturn this[typeIndexer oIndexer] { 
     get { return oReturn[oIndexer]; } 
     set { oReturn[oIndexer] = value; } 
    } 
} 

... et que vas-tu parier que ça marche !?

Euh, pas tout à fait! Toujours se plaindre de typeIndexer (vouloir un type "int-capable"), mais beaucoup plus mieux! J'ai également ajouté dans un constructeur pour résoudre ce problème "Je ne peux pas vraiment régler oReturn to anything" problème =)

Mais même cela ne semble pas tout à fait raison (Les tableaux sont toujours indexés par INTs, non? pas besoin de typeIndexer) ... Je vais devoir regarder à nouveau à Wurk demain =)

+1

Est-ce que vous réalisez que l'indexeur de l'objet retournerait une instance du même type? Est-ce que cela signifie être un arbre/graphique? –

+0

Je ne suis pas certain que je suis Matthew ... si l'oReturn sous-jacent était un bool [], le retour ... agh ... le voir maintenant =) C'était une faute de frappe/bug ... éditer la question originale en 3 .. .2 ... – Campbeln

Répondre

3

vous voulez quelque chose le long de ces lignes:

public class ParameterizedProperty<typeReturn, typeIndexer> { 
    private Dictionary<typeIndexer, typeReturn> oReturn = new Dictionary<typeIndexer, typeReturn>(); 

    public typeReturn this[typeIndexer oIndexer] { 
     get { return oReturn[oIndexer]; } 
     set { oReturn[oIndexer] = value; } 
    } 
} 
+0

Cela fonctionnerait en effet pour mes fins, mais il semble un peu lourd en utilisant un dictionnaire pour accomplir ce qu'une chaîne [] ou bool [] ferait (peu importe ce problème indexeur embêtant;) I devinez qu'une approche de dictionnaire obtiendra mon vote ... mais pour quelques jours au moins je vais tenir dehors/experiment =) – Campbeln

1

Puisque vous êtes évidemment pas préoccupé par la fixation spécifique logique métier pour le getter ou le setter pour cette propriété indexée (comme vous pourriez le faire avec l'indexeur par défaut en C# ou toute propriété en VB.NET), vous avez besoin d'une mécanisme d'orage pour accomplir ceci.

public class ParameterizedProperty<TReturn, TIndexer> 
{ 
    private Dictionary<TIndexer, TReturn> storage = new Dictionary<TIndexer, TReturn>(); 

    public TReturn this[TIndexer index] 
    { 
     get 
     { 
      TReturn output; 

      storage.TryGetValue(index, out output); 

      return output; 
     } 
     set { storage[index] = value; } 
    } 
} 

Mais tout cela fait vraiment est vous fournir une construction similaire à un Dictionary mais ne jette pas une exception lorsqu'un index n'est pas présent.

+0

J'aime l'utilisation du TryGetValue (je devrai le regarder, mais je ferais deviner "default (TReturn)" est placé en sortie si le get échoue?). Et oui ... pas besoin d'attacher la fonctionnalité add'l à ces indexeurs/propriétés (pourrait toujours surcharger/implémenter un crochet je suppose), je veux juste ...Chaîne publique [] ID { get {return ga_sIDs; } } ... sans exposer ga_sID à l'appelant (ni à toutes ses propriétés/méthodes). – Campbeln

+1

@CampbeIn: Oui, 'default (TReturn)' est ce qui est mis dans la variable 'out' si la récupération échoue. –

+0

@CampbeIn: De plus, un 'Dictionary' est le seul moyen d'obtenir ce que vous cherchez si vous voulez un schéma d'indexation arbitraire. Un tableau ne fonctionnera pas. Le 'Dictionary' n'est pas un objet particulièrement lourd. –