Дизайн класса для неизвестного числа параметров типа - PullRequest
4 голосов
/ 06 декабря 2010

Мне нужно спроектировать класс, который может содержать произвольное количество типов, хотя я не знаю тип и количество этих значений во время разработки. Например - я мог бы инициализировать класс с 2-мя целочисленными значениями и длинным или только одним целым числом. Я также хотел бы по возможности избегать бокса (используя тип «объект»). Каждый тип также имеет имя, поэтому внутренний словарь, содержащий значения, может выглядеть как

Dictionary<string,object> nameValues;//Boxing!

и конструктор может выглядеть как

MyClass(params object[] values) { ... }

Я мог бы создать экземпляр, подобный этому

MyClass mc = new MyClass("intVal",3,"doubleVal",3.5,"dateTimeVal",DateTime.Now);

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

Редактировать: Должна быть также возможность указать значение 'string' в качестве параметра. Сначала я упоминал только типы значений, но это уже не так!

Ответы [ 4 ]

2 голосов
/ 06 декабря 2010

попробуйте

Dictionary<string, ValueType> x = new Dictionary<string, ValueType>();
x.Add("1",1);
x.Add("2", 23.33m);
x.Add("3", new MyStruct());
x.Add("4", new object()); // compile-time error
2 голосов
/ 06 декабря 2010

Если вы заранее знаете возможные типы, вы можете использовать отдельный словарь для каждого типа, тогда вам не нужно боксировать при чтении значений обратно.

Например, используя существующую структуру кода:

class MyClass
{
    private Dictionary<string, int> intValues = new Dictionary<string, int>();
    private Dictionary<string, double> doubleValues = new Dictionary<string, double>();
    private Dictionary<string, DateTime> dateTimeValues = new Dictionary<string, DateTime>();

    public MyClass(params object[] values)
    {
        if (values.Length % 2 != 0)
            throw new ArgumentException("invalid values!", "values");
        for (int i = 0; i < values.Length; i += 2)
        {
            string key = values[i].ToString();
            object value = values[i + 1];
            if (value is int)
                intValues.Add(key, (int)value);
            else if (value is double)
                doubleValues.Add(key, (double)value);
            else if (value is DateTime)
                dateTimeValues.Add(key, (DateTime)value);
        }
    }
}
2 голосов
/ 06 декабря 2010

Лично я бы не боялся маленького бокса; если вы не определили и не доказали, что это проблема, это, вероятно, наименьшая из ваших проблем. Но как насчет анонного типа:

var mc = new { intVal = 3, doubleVal = 3.5, dateTimeVal = DateTime.Now };

Единственная проблема заключается в том, что вне этого метода единственный способ вернуть эти значения - это отражение. Который не обязательно проблема. Но во многих отношениях Dictionary<string,object> (хотя и более избыточный) намного проще.

0 голосов
/ 06 декабря 2010

может быть что-то вроде ниже

public class ValueHolder
{
    public ValueType[] Values { get; set; }
    public string[] NonValueType { get; set; }
}

public class SomeValueType<T> where T:ValueHolder
{
    Dictionary<string, T> tempDict = new Dictionary<string, T>();


    public SomeValueType(T val,string keyName)
    {
        if(!tempDict.Keys.Contains(keyName))
             tempDict.Add(keyName, val);
    }

}

использует

        ValueType[] arr = new ValueType[] { 1, 1.1, DateTime.Now };
        ValueHolder vh = new ValueHolder();
        vh.Values = arr;
        vh.NonValueType = new string[] { "temp", "s" };
        SomeValueType<ValueHolder> temp = new SomeValueType<ValueHolder>(vh, "key");
...