小弟对动态创建比较陌生,希望得到大家帮助。
需求是这样的:数据库各个表都有value这一列,但是value的类型不确定,可能是double,string,int,但肯定都是基本类型。
不知道怎么才能把这些value在c#中转成对应的基本类型?
是否要用到反射?

解决方案 »

  1.   

    官方http://www.tracefact.net/CLR-and-Framework/Reflection-Part4.aspx
      

  2.   


    我试过用Assembly和Activator创建,按我的理解出来的还是object,好像也必须强制类型转换,不能直接用。
    我想做的是比如给 "double" 和 “123.0” 直接能得到 double 型的 123.0,不知道有没有这样的方法。
      

  3.   

    没必要用反射,直接用Convert.ToInt32,Convert.ToString,Convert.ToDouble就可以,
      

  4.   

    数据库的行读取到DataTable中,.Net已经帮你反射好了,
      

  5.   

    的确和反射一点关系都没有。
    第一,通过用sql读取数据表字段类型(当然你也可以采取别的方法)SELECT name AS TableName FROM sysobjects WHERE (xtype = 'U') AND (name <> 'dtproperties') ORDER BY name
    --
    SELECT sysobjects.name AS TableName, syscolumns.name AS FieldName, systypes.name AS FieldType
                            FROM syscolumns INNER JOIN
                            sysobjects ON syscolumns.id = sysobjects.id AND sysobjects.xtype = 'U' AND 
                            sysobjects.name <> 'dtproperties' INNER JOIN
                            systypes ON syscolumns.xtype = systypes.xtype AND 
                            syscolumns.xusertype = systypes.xusertype第二,转换:/// <summary>
            /// 将字段类型抓换为.Net可识别的类型
            /// </summary>
            /// <param name="type">数据库字段类型名称</param>
            /// <returns>.Net类型名称</returns>
            private string GetNetType(string type)
            {
                switch (type.ToLower())
                {
                    case "bigint":
                        return SqlDbType.BigInt.ToString();
                    case "binary":
                        return SqlDbType.Binary.ToString();
                    case "bit":
                        return SqlDbType.Bit.ToString();
                    case "char":
                        return SqlDbType.Char.ToString();
                    case "datetime":
                        return SqlDbType.DateTime.ToString();
                    case "decimal":
                        return SqlDbType.Decimal.ToString();
                    case "float":
                        return SqlDbType.Float.ToString();
                    case "image":
                        return SqlDbType.Image.ToString();
                    case "int":
                        return SqlDbType.Int.ToString();
                    case "money":
                        return SqlDbType.Money.ToString();
                    case "nchar":
                        return SqlDbType.NChar.ToString();
                    case "ntext":
                        return SqlDbType.NText.ToString();
                    case "numeric":
                        return SqlDbType.Decimal.ToString();
                    case "nvarchar":
                        return SqlDbType.NVarChar.ToString();
                    case "real":
                        return SqlDbType.Real.ToString();
                    case "smalldatetime":
                        return SqlDbType.SmallDateTime.ToString();
                    case "smallint":
                        return SqlDbType.SmallInt.ToString();
                    case "smallmoney":
                        return SqlDbType.SmallMoney.ToString();
                    case "sql_variant":
                        return SqlDbType.Variant.ToString();
                    case "text":
                        return SqlDbType.Text.ToString();
                    case "timestamp":
                        return SqlDbType.Timestamp.ToString();
                    case "tinyint":
                        return SqlDbType.TinyInt.ToString();
                    case "uniqueidentifier":
                        return SqlDbType.UniqueIdentifier.ToString();
                    case "varbinary":
                        return SqlDbType.VarBinary.ToString();
                    case "varchar":
                        return SqlDbType.VarChar.ToString();
                    case "xml":
                        return SqlDbType.Xml.ToString();
                    default:
                        return SqlDbType.Udt.ToString();
                }
            }
      

  6.   

    看不懂你说的时候什么。或者,你可能犯了一个最简单错误。所谓一个object value;这个变量所引用的对象的“基本类型”,它本身就是基本类型。比如说它引用一个int,那么value它本身就引用一个int;比如说它引用一个string,那么value它本身就是引用一个string。你试一试代码object a = 1234;
    a = "1234";
    Type type=a.GetType();那么你怎么会弄成什么“我要转换一个基本类型”这种话?我想大多是你自己都没有搞明白编程跟执行的区别吧。你想说明value所引用的对象的类型是不确定的,又想让我们给你写一个代码你好在声明时就去写下value的“基本类型”,这就是一个不可能完成的悖论,是个难以解释通顺的任务。
      

  7.   

    在你使用ado.net的DbDataReader读取一个字段,例如 reader["value"] 的时候,它声明的是 object 类型,而它引用的就是基本类型。还要怎样“转换”呢?
      

  8.   


    呃,可能我之前表述有问题,有些概念也不是很清。
    数据已经读到DataTable里了,Convert我也知道。之前比如知道字段“Id”是整型那就直接
    int i = (int)table.Rows[0]["Id"]可以的。
    但是假设现在“Id”的类型要运行时才知道,那上面那行代码的功能要怎么实现?
      

  9.   


    代码我试了,a.GetType()FullName是System.String. 这个a也没法直接当string来用,比如用Split方法,不还得强制类型转换 (string)a 么。
    数据库我也不是很熟,我读到datatable里的值都是object,都要用比如
    int id = (int)table.Rows[0]["Id"]这样强制类型转换。但是这只能是我事先知道"Id"是整型才能这么写啊,如果字段“value”类型是不知道的情况下,我编码的时候应该怎么写实现跟上面一样的效果,比如让整型就是整形,字符串就是字符串?我能想到的只有用个switch case,但感觉这样太难看了,不知道有没有其他简洁的实现方法。
      

  10.   


    switch case其实是最简单的实现方法,当然你可以用多态性代替switch case,定义一个基类,比如abstract class BClass
    {
        private static LinkedList<BClass> m_lstRegisteredClass=new LinkedList<BClass>();    public abstract void Process(object value);
        public abstract Type GetValueType();    public static void RegisterClass(BClass rClass)
        {
            lstRegisteredClass.AddLast(rClass);
        }    public static BClass SelectInstance(object value)
        {
            foreach(BClass rClass in lstRegisteredClass)
            {
                 if (value.GetType()==rClass.GetValueType())
                     return rClass;
            }
            return null;
        }
    }然后把case里的内容放在派生类的Process重载中,switch的内容改为:BClass rClass=BClass.SelectInstance(value);
    rClass.Process(value);这样看起来很简洁,不过首先要注册BClass派生类,也可以把BClass派生类写在xml文件中,让BClass通过反射创建派生类,