开发者

How do you deal with object type switching?

开发者 https://www.devze.com 2023-03-04 04:15 出处:网络
In C# from time to time the issue creeps out. Usually I get an object value and then I have to call "real" function for it. Something like this:

In C# from time to time the issue creeps out. Usually I get an object value and then I have to call "real" function for it. Something like this:

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

or

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

I can see a textual pattern here, but I didn't come up with solution which would deal once for good with all the dirty work.

How do you deal it? You receive the object value and you have to either set it or pass it but not as an object but concrete type (PODs, Nullable of PODs and string) and...?

Edits

Complete example (this one is the cause of the question):

    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(re开发者_StackOverflowcord, val, null);
        }

        return record;


    }


You could use a strategy pattern. Just put the strategies for each type in a hashtable and then you don't need the switches. However, you'll need one class per strategy. It is especially useful if you have complex logic.

If the logic is rather simple you could also use a Hashtable containing delegates.

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

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


You could clean it up a bit using the is operator:

if (MyType is BaseType)...
0

精彩评论

暂无评论...
验证码 换一张
取 消