【问题标题】:How to convert a TypeCode to an actual type?如何将 TypeCode 转换为实际类型?
【发布时间】:2011-08-20 10:04:42
【问题描述】:

在下面的代码中,我得到colType,这是该类型的代码。但是我如何将该数字转换为实际类型?谢谢!!

for (int j = 0; j < dvColumns.Count; j++)
{
    // Get the name of the column.
    drvCols = dvColumns[j];
    colName = drvCols.Row.ItemArray[3].ToString();

    // Get columns data type code and save it off.
    colType = Convert.ToInt32(drvCols.Row.ItemArray[11]);
}

【问题讨论】:

  • 举个输入的例子。
  • 您必须对 colType 的值使用 switch-case。
  • 问题是我不知道什么类型的数字代表什么类型。例如,返回的数字之一是 72。我怎么知道 72 应该代表什么类型?
  • @user259286 您可以将其转换为 TypeCode。请参阅下面对我的答案的更新。
  • 你是唯一可能知道返回数字的值是什么意思的人。如果你不知道这一点,其他人怎么知道?谁负责将数字放入该特定列?问他们。

标签: c# types


【解决方案1】:

更简单:

Type type = Type.GetType("System." + colType);

如果要将值转换为该类型,可以直接使用类型代码

Convert.ChangeType(value, colType);

【讨论】:

【解决方案2】:

使用 switch 语句:

    public static Type ToType(this TypeCode code)
    {
        switch (code)
        {
            case TypeCode.Boolean:
                return typeof(bool);

            case TypeCode.Byte:
                return typeof(byte);

            case TypeCode.Char:
                return typeof(char);

            case TypeCode.DateTime:
                return typeof(DateTime);

            case TypeCode.DBNull:
                return typeof(DBNull);

            case TypeCode.Decimal:
                return typeof(decimal);

            case TypeCode.Double:
                return typeof(double);

            case TypeCode.Empty:
                return null;

            case TypeCode.Int16:
                return typeof(short);

            case TypeCode.Int32:
                return typeof(int);

            case TypeCode.Int64:
                return typeof(long);

            case TypeCode.Object:
                return typeof(object);

            case TypeCode.SByte:
                return typeof(sbyte);

            case TypeCode.Single:
                return typeof(Single);

            case TypeCode.String:
                return typeof(string);

            case TypeCode.UInt16:
                return typeof(UInt16);

            case TypeCode.UInt32:
                return typeof(UInt32);

            case TypeCode.UInt64:
                return typeof(UInt64);
        }

        return null;
    }

【讨论】:

    【解决方案3】:

    我认为在 .NET Framework 中没有任何方法可以本地执行此操作,因为我看到的所有示例都使用大 switch 语句来处理转换(例如:here)。

    但是,如果您试图获取类型作为将对象转换为该类型的中间步骤,则始终可以使用接受 TypeCode 作为参数的Convert.ChangeType

    double d = -1.234;
    int i = (int)Convert.ChangeType(d, TypeCode.Int32);
    

    不幸的是,没有看到您要做什么,我真的不能说ChangeType 是否会有所帮助。

    编辑:

    要将int 转换为OleDbType,您只需转换它:

    int i = 72; //72 is the value for OleDbType.Guid
    if(Enum.IsDefined(typeof(System.Data.OleDb.OleDbType), i))
    {
        System.Data.OleDb.OleDbType dbType = (System.Data.OleDb.OleDbType)i;
        Console.WriteLine(dbType);
    }
    else
        Console.WriteLine("{0} is not defined for System.Data.OleDb.OleDbType", i);
    

    【讨论】:

    • 如果有Convert.TryChangeType&lt;T&gt;(d, TypeCode.Int32, out T v) 就好了,因为在某些情况下您可能会使用switch(TypeCode) 来处理值类型。否则,您最终会对d 执行各种检查,以确保Convert 不会引发异常。
    【解决方案4】:

    OP 中问题的确切答案(使用 schoetbi 的 提示)将是:

    public static Type GetType(TypeCode code)
        {         
            return Type.GetType("System." + Enum.GetName(typeof(TypeCode), code));
        }
    

    【讨论】:

    • 我已经测试过了,它对我有用,没有任何问题
    【解决方案5】:

    我喜欢这样做。我更喜欢使用静态表而不是大开关或反射。

    /// <summary>
    /// Table that maps TypeCode to it's corresponding Type.
    /// </summary>
    static IReadOnlyDictionary<TypeCode, Type> TypeCodeToTypeMap = new Dictionary<TypeCode, Type>
    {
        { TypeCode.Boolean, typeof(bool) },
        { TypeCode.Byte, typeof(byte) },
        { TypeCode.Char, typeof(char) },
        { TypeCode.DateTime, typeof(DateTime) },
        { TypeCode.DBNull, typeof(DBNull) },
        { TypeCode.Decimal, typeof(decimal) },
        { TypeCode.Double, typeof(double) },
        { TypeCode.Empty, null },
        { TypeCode.Int16, typeof(short) },
        { TypeCode.Int32, typeof(int) },
        { TypeCode.Int64, typeof(long) },
        { TypeCode.Object, typeof(object) },
        { TypeCode.SByte, typeof(sbyte) },
        { TypeCode.Single, typeof(Single) },
        { TypeCode.String, typeof(string) },
        { TypeCode.UInt16, typeof(UInt16) },
        { TypeCode.UInt32, typeof(UInt32) },
        { TypeCode.UInt64, typeof(UInt64) }
    };
    
    /// <summary>
    /// Convert a TypeCode ordinal into it's corresponding Type instance.
    /// </summary>
    public static Type ToType(this TypeCode code)
    {
        Type type = null;
    
        TypeCodeToTypeMap.TryGetValue(code, out type);
    
        return type;
    }
    

    【讨论】:

    • switch 是一个实现细节,很容易隐藏在扩展方法中。由于编译而不是通过映射运行时解码,switch 应该比字典快。不过,我确实喜欢这些类型的地图的灵活性。
    • 很久以前,当我深入研究 C++ 时,Scott Meyers 告诉我 switch 语句通常运行 O(n),而我们通常可以做得更好。所以我倾向于使用地图/字典/哈希表,不仅是为了可读性,而且通常是为了 O(1) 性能。我想对此进行分析,以了解它在 C# 中的真正重要性。
    • 好吧,事实证明它们是可比的。在 Release 版本中,该开关在 Dictionary 上的优势非常小。在 Debug 构建中(如果有人关心的话),Dictionary 实际上击败了开关。很有意思。我的收获是编译器优化了开关,使其更像哈希表。所以在性能方面,它是一种洗涤。做你认为更具可读性的事情。 gist.github.com/BrandonLWhite/d823dcbddc256be6fd879b7be7d3960f
    猜你喜欢
    • 2012-08-27
    • 2020-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-07
    • 2016-06-08
    相关资源
    最近更新 更多