2017-01-30 4 views
1

Existe-t-il un moyen de réaliser quelque chose comme ça? J'ai trouvé cette dynamique peut être une solution mais son de .NET 4.0+:/C# - Dictionnaire, Puis-je définir le type de valeur dans le constructeur? .NET 2.0

public class Message 
     { 
      public int ID; 
      Dictionary<dynamic, dynamic> dict 

      public Message(int ID, Dictionary<dynamic, dynamic> Data) 
      { 
       this.ID = ID; 
       dict = Data 
      } 
     } 

La raison est parce que je veux parfois dictionnaire avec chaîne: string et parfois avec la chaîne: int donc je voudrais avoir cette classe un peu dynamique et pas 2 classes.

+1

Pouvez-vous créer le générique de la classe 'Message' aussi ou n'est-ce pas une option? –

+2

Ainsi, 'Dictionary '? Habituellement, quand vous pensez que vous avez besoin de 'dynamic', ce n'est pas le cas. – CodeCaster

+0

@CodeCaster Le studio visuel dit que vous ne pouvez pas transmettre la chaîne de dictionnaire: chaîne en chaîne: objet –

Répondre

4

Si votre dictionnaire peut contenir celui-là en même temps et celui-ci à un autre moment, ce devrait être en fait deux dictionnaires différents. Cela va avec le principe SOLID, ce qui signifie que n'importe quelle classe et même n'importe quel membre d'une classe sert un seul but. Avoir un objet faisant l'un dans le scénario 1 et quelque chose de différent dans le scénario 2 est généralement une conception brisée et vous devriez envisager de créer deux choses différentes.

Alternativly aller avec les génériques, c'est Dictionary<T, U> où vous devez passer T et U à votre Message -class:

public class Message<T, U> 
{ 
    public int ID; 
    private readonly Dictionary<T, U> dict; 

    public Message(int ID, Dictionary<T, U> Data) 
    { 
     this.ID = ID; 
     dict = Data; 
    } 
} 

Maintenant, vous pouvez faire des cas comme celui-ci:

var myDict = new Dictionary<string, string>(); 
var m = new Message<string, string>(0, myDict); 

qui sera automatiquement déduire les bons types pour T et U en fonction de votre définition de myDict.

+0

Il ne semble pas qu'il remplisse automatiquement les types. J'ai l'erreur que «Utilisation du type générique» Message nécessite deux arguments de type »à la ligne' var m = nouveau Message (0, myDict) ' –

+0

' Dictionary myDict = new Dictionary { {"key1", "data1"}, {"key2", "data2"} }; ' –

+0

En effet, cela ne fonctionne pas pour le constructeur.Vous devez également fournir les paramètres génériques, comme indiqué dans mon dernière édition – HimBromBeere

0

Vous devez utiliser les médicaments génériques

public class MyClass<T> 
    { 
     private readonly Dictionary<string, T> _data; 

     public MyClass(Dictionary<string, T> newData) 
     { 
      _data = newData; 
     } 

     public Dictionary<string, T> Data 
     { 
      get { return _data;} 
     } 

    } 
+0

Pas vrai. Vous pouvez définir readonly via un constructeur. – Wheels73

1

La meilleure façon est de créer une méthode de fabrication générique, et de cette façon vous n'avez même pas à la charge de l'utilisateur avec les types:

public static class MessageFactory 
{ 
    public static Message<TKey, TValue> Create<TKey, TValue>(int ID, IDictionary<TKey, TValue> data) 
     => new Message<TKey, TValue>(ID, data); 

    public class Message<TKey, TValue> 
    { 
     public Message(int ID, IDictionary<TKey, TValue> data) { ... } 
    } 
} 

et maintenant, l'utilisation est presque le même que votre solution dynamic, mais beaucoup plus sûr:

var message = MessageFactory.Create(1, someDictionary); 

L'inférence de type prendra en charge l'élaboration des types TKey et TValue.

P.S. Rendre Message<,> imbriqué ou non est entièrement facultatif. Je l'aime de cette façon afin de désencombrer autant que possible l'espace de noms.