当前位置:编程学习 > C#/ASP.NET >>

如何用反射创建基本类型?

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

http://www.tracefact.net/CLR-and-Framework/Reflection-Part4.aspx --------------------编程问答--------------------
引用 1 楼 lmaohuanl 的回复:
官方

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


我试过用Assembly和Activator创建,按我的理解出来的还是object,好像也必须强制类型转换,不能直接用。
我想做的是比如给 "double" 和 “123.0” 直接能得到 double 型的 123.0,不知道有没有这样的方法。 --------------------编程问答-------------------- 这和反射没毛的关系。 --------------------编程问答--------------------
引用 3 楼 raistlin010 的回复:
这和反射没毛的关系。
   --------------------编程问答--------------------
引用 3 楼 raistlin010 的回复:
这和反射没毛的关系。


那请教一下有啥思路么? --------------------编程问答-------------------- 没必要用反射,直接用Convert.ToInt32,Convert.ToString,Convert.ToDouble就可以, --------------------编程问答-------------------- 数据库的行读取到DataTable中,.Net已经帮你反射好了, --------------------编程问答-------------------- 的确和反射一点关系都没有。


第一,通过用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();
            }
        }
--------------------编程问答-------------------- 看不懂你说的时候什么。或者,你可能犯了一个最简单错误。

所谓一个
object value;
这个变量所引用的对象的“基本类型”,它本身就是基本类型。比如说它引用一个int,那么value它本身就引用一个int;比如说它引用一个string,那么value它本身就是引用一个string。你试一试代码
object a = 1234;
a = "1234";
Type type=a.GetType();


那么你怎么会弄成什么“我要转换一个基本类型”这种话?我想大多是你自己都没有搞明白编程跟执行的区别吧。你想说明value所引用的对象的类型是不确定的,又想让我们给你写一个代码你好在声明时就去写下value的“基本类型”,这就是一个不可能完成的悖论,是个难以解释通顺的任务。 --------------------编程问答-------------------- 在你使用ado.net的DbDataReader读取一个字段,例如 reader["value"] 的时候,它声明的是 object 类型,而它引用的就是基本类型。还要怎样“转换”呢? --------------------编程问答--------------------
引用 7 楼 stonespace 的回复:
数据库的行读取到DataTable中,.Net已经帮你反射好了,


呃,可能我之前表述有问题,有些概念也不是很清。
数据已经读到DataTable里了,Convert我也知道。之前比如知道字段“Id”是整型那就直接
int i = (int)table.Rows[0]["Id"]可以的。
但是假设现在“Id”的类型要运行时才知道,那上面那行代码的功能要怎么实现? --------------------编程问答--------------------
引用 9 楼 sp1234 的回复:
看不懂你说的时候什么。或者,你可能犯了一个最简单错误。

所谓一个C# code
object value;
这个变量所引用的对象的“基本类型”,它本身就是基本类型。比如说它引用一个int,那么value它本身就引用一个int;比如说它引用一个string,那么value它本身就是引用一个string。你试一试代码C# code
object a = 1234;
a = "1234";
……


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

看不懂你说的时候什么。或者,你可能犯了一个最简单错误。

所谓一个C# code
object value;
这个变量所引用的对象的“基本类型”,它本身就是基本类型。比如说它引用一个int,那么value它本身就引用一个int;比如说它引用一个string,那么value它本身就是引用一个string。你试一试代码C# code
object……


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通过反射创建派生类,


补充:.NET技术 ,  C#
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,