Как вы справляетесь с переключением типов объектов? - PullRequest
1 голос
/ 07 мая 2011

В C # время от времени проблема выползает. Обычно я получаю значение объекта, а затем мне приходится вызывать «настоящую» функцию для него. Примерно так:

if (type==typeof(byte))
  val = rs.GetByte(col);
else if (type==typeof(int))
  val = rs.GetInt32(col);
...

или

if (type==typeof(byte))
  Call((byte)val);
else if (type==typeof(int))
  Call((int)val);
...

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

Как вы справляетесь с этим? Вы получаете значение объекта, и вам нужно либо установить его, либо передать его, но не как объект, а конкретный тип (POD, Nullable of PODs и string) и .. .

редактирует

Завершить Пример (этот вопрос является причиной вопроса):

    protected IRecord ReadRecord()
    {
        if (!ResultSet.Read())
            return null;

        IRecord record = CreateIRecord();

        var type = record.GetType();
        int column = -1;

        foreach (var prop in type.GetProperties())
        {
            ++column;
            object val;

            if (prop.PropertyType == typeof(byte))
                val = ResultSet.GetByte(column);
            else if (prop.PropertyType == typeof(byte?))
                val = ResultSet.GetSqlByte(column).ToNullable();
            else if (prop.PropertyType == typeof(int))
                val = ResultSet.GetInt32(column);
            else if (prop.PropertyType == typeof(int?))
                val = ResultSet.GetSqlInt32(column).ToNullable();
            else if (prop.PropertyType == typeof(double))
                val = ResultSet.GetDouble(column);
            else if (prop.PropertyType == typeof(double?))
                val = ResultSet.GetSqlDouble(column).ToNullable();
            else if (prop.PropertyType == typeof(DateTime))
                val = ResultSet.GetDateTime(column);
            else if (prop.PropertyType == typeof(DateTime?))
                val = ResultSet.GetSqlDateTime(column).ToNullable();
            else if (prop.PropertyType == typeof(string))
                val = ResultSet.GetString(column);
            else
                throw new ArgumentException("Invalid property type {0}".Expand(prop.PropertyType.ToString()));

            prop.SetValue(record, val, null);
        }

        return record;


    }

Ответы [ 2 ]

2 голосов
/ 07 мая 2011

Вы можете немного его почистить, используя оператор is:

if (MyType is BaseType)...
2 голосов
/ 07 мая 2011

Вы можете использовать шаблон стратегии. Просто поместите стратегии для каждого типа в хеш-таблицу, и тогда вам не нужны переключатели. Тем не менее, вам понадобится один класс на стратегию. Это особенно полезно, если у вас сложная логика.

Если логика довольно проста, вы также можете использовать Hashtable, содержащий делегаты.

//pseudo code
handlers.put(typeof(int), delegate(object value) { return something.GetInt32(value); });

//like this
var handler = handlers[type];
handler.Invoke(val);
...