将对象类型数据转换为值类型的最佳方法

时间:2011-11-09 03:16:41

标签: c# .net object unboxing

我的任务是创建使用数据读取器从数据库中获取数据的代码,我很好奇下面的3种方法之间的最佳实践,我可以使用以下方法从我的数据读取器转换数据默认使用一种对象获取。

    internal static RoomType SelectRoomType(int roomTypeID)
    {
        SqlCommand commRoomTypeSelector = ConnectionManager.MainConnection.CreateCommand();
        commRoomTypeSelector.CommandType = CommandType.StoredProcedure;
        commRoomTypeSelector.CommandText = "Rooms.asp_RMS_RoomType_Select";
        commRoomTypeSelector.Parameters.AddWithValue("RoomTypeID", roomTypeID);

        SqlDataReader dreadRoomType = commRoomTypeSelector.ExecuteReader();
        if (dreadRoomType.FieldCount != 0)
        {
            dreadRoomType.Read();
            RoomType roomType = new RoomType();
            roomType.RoomTypeID = (int)dreadRoomType["RoomTypeID"];
            roomType.RoomTypeName = (string)dreadRoomType["RoomType"];
            roomType.IsActive = ((string)dreadRoomType["IsActive"]).ToUpper() == "Y";
            roomType.LastEditDate = (string)dreadRoomType["LastEditDate"] != string.Empty ? DateTime.Parse((string)dreadRoomType["LastEditDate"]) : DateTime.MinValue;
            roomType.LastEditUser = (string)dreadRoomType["LastEditUser"];
            dreadRoomType.Close();
            return roomType;
        }
        dreadRoomType.Close();
        return null;
    }

让我感到困惑的是取消装箱部分,根据http://msdn.microsoft.com/en-us/library/yz2be5wk.aspx 拳击和拆箱非常昂贵且应该避免。我知道我可以使用

   int.Parse(dreadRoomType["RoomTypeID"].ToString())

而不是

   roomType.RoomTypeID = (int)dreadRoomType["RoomTypeID"];

问题是,是否仍然存在以更有效的方式转换此数据的方法,以及如果您不希望使用这两种方式的可能方式。在此先感谢所有的帮助和建议被接受:)

5 个答案:

答案 0 :(得分:3)

您可以使用SqlDataReader.GetInt32()来避免再次转换/解析为int,为此您必须知道整数在所选列中的索引:

roomType.RoomTypeID = dreadRoomType.GetInt32(0);

答案 1 :(得分:3)

拳击不 昂贵。

其他替代方案无济于事;一旦你有一个object,它就已经装箱了。
特别是字符串解析可能比拳击更昂贵。 (虽然我没有测量过)

如果存在类型化的API,您可以使用它来避免装箱(例如,呼叫GetInt32) (尽管这些类型化的方法有时只是围绕无类型方法的包装器,因此它们也会包装)


底线:不要担心

该指南告诉您在可能的情况下使用类型(通用)集合首先避免装箱事件

答案 2 :(得分:2)

如果装箱/取消装箱是“慢”(它确实不是)...为什么转换为字符串并且返回不是非常慢? (这真的是一种浪费:装箱/拆箱显着更快。)我会首先确保存在性能问题,然后再担心它,但是...... < / p>

根据我的经验,对于我的数据,其中包括一次加载的数千个项目,我发现预先确定列索引可以获得更多的性能(但是使用GetOrdinal动态地执行此操作!),然后我不担心其余部分:)

对于一个项目,根据这篇文章,我甚至不会担心序数:这是一个完全不同的用例,“昂贵的”部分正在与数据库交谈。

快乐的编码。

答案 3 :(得分:1)

装箱和拆箱并不像解析字符串和提取int那样昂贵。请在进行过早优化之前进行分析。

答案 4 :(得分:0)

    private static void GetValue<T>(object o, ref T defaultValue)
    {
        try
        {
            if (defaultValue == null)
            {
                throw new Exception("Default value cannot be null");
            }
            else if (o != null)
            {
                if ((o is T))
                {
                    defaultValue = (T)o;
                }
            }
        }
        catch (Exception)
        {
            throw;
        }
    }

您可以使用上述方法将对象转换为任何基本数据类型,如下所示 转换为dateTime

    public static DateTime GetDateTime(object o, DateTime defaultValue)
    {
        try
        {
            GetValue<DateTime>(o, ref defaultValue);
            return defaultValue;
        }
        catch (Exception)
        {
            throw;
        }
    }

转换为整数

    public static int GetInteger(object o, int defaultValue)
    {
        try
        {
            GetValue<int>(o, ref defaultValue);
            return defaultValue;
        }
        catch (Exception)
        {
            throw;
        }
    }

在此处参考并下载包含所有基本数据类型的完整代码 http://www.dotnetlines.com/Blogs/tabid/85/EntryId/39/Convert-Object-type-into-its-specific-data-type-using-a-Generic-Method.aspx