2017-01-30 13 views
1

Есть ли способ достичь чего-то подобного? Я обнаружил, что динамика может быть решением, но его с .NET 4.0+:/C# - Словарь, могу ли я установить тип значения в конструкторе? .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 
      } 
     } 

Причина, потому что иногда я хочу словарь со строкой: строка, а иногда со строкой: Int, поэтому я хотел бы иметь этот класс немного динамический, а не 2 класса.

+1

Можете ли вы создать класс 'Message' generic слишком или это не вариант? –

+2

Итак, 'Словарь '? Обычно, когда вы думаете, что вам нужна «динамика», вы этого не делаете. – CodeCaster

+0

@CodeCaster Визуальная студия говорит, что вы не можете передать строку слова: string в строку: object –

ответ

4

Если ваш словарь может удерживать этот файл за один раз, а другой в другое время, это должен быть фактически два разных словаря. Это связано с принципом SOLID, что означает, что любой класс и даже любой член класса обслуживает один единственный цель. Наличие объекта, делающего одно в сценарии 1, и что-то другое в сценарии 2, как правило, является сломанным дизайном, и вы должны подумать о создании двух разных вещей.

Alternativly идут с обобщениями, это Dictionary<T, U>, где вы должны пройти T и U к вашему Message -класса:

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; 
    } 
} 

Теперь вы можете сделать экземпляры, как это:

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

, который будет автоматически выведите правильные типы для T и U в зависимости от вашей дефиниции myDict.

+0

Не похоже, что он автоматически заполняет типы. У меня есть ошибка, что 'Использование родового типа 'Сообщение требует двух аргументов типа' в строке 'var m = new Message (0, myDict)' –

+0

'Словарь <строка, строка> myDict = новый словарь <строка, строка> { {"key1", "data1"}, {"key2", "data2"} }; ' –

+0

Действительно, это не работает для конструктора. Вы также должны указать общие параметры, как показано на моем Последнее редактирование: – HimBromBeere

0

Вы должны использовать дженерики

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

Неправда. Вы можете установить readonly через contructor. – Wheels73

1

Лучший способ создать универсальный фабричный метод, и таким образом, вы даже не должны утяжелять пользователю типов:

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) { ... } 
    } 
} 

а теперь использование почти такой же, как ваш dynamic решение, но гораздо безопаснее:

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

Тип вывода будет заниматься разработкой типов TKey и TValue.

P.S. Создание Message<,> вложенное или нет полностью необязательно. Мне нравится это так, чтобы максимально разрешить пространство имен.