C#:返回系统数据类型的聪明助手类

标签 c# .net

我正在使用的数据库只能支持我为其编写代码的数据类型。

我创建了一个带有可用类型列表的 Enum 参数。

public enum TableDataType
{
  None=0, String=1, Integer=2, Character=3, Boolean=4, DateTime=5, Decimal=6
}

这可行,但我仍然需要处理进入和返回数据结构的过程:

TableDataType GetMyType(DataGridViewColumn col) {
  TableDataType type;
  if (col.ValueType == typeof(bool)) {
    type = TableDataType.Boolean;
  } else if (col.ValueType == typeof(char)) {
    type = TableDataType.Character;
  } else if (col.ValueType == typeof(DateTime)) {
    type = TableDataType.DateTime;
  } else if (col.ValueType == typeof(Decimal)) {
    type = TableDataType.Decimal;
  } else if (col.ValueType == typeof(Int32)) {
    type = TableDataType.Integer;
  } else if (col.ValueType == typeof(string)) {
    type = TableDataType.String;
  } else {
    throw new ArgumentException(string.Format("Data Type of '{0}' is not supported.", col.ValueType));
  }
  return type;
}

然后有相反的代码...

Type GetSystemType(TableDataType myType) {
  Type sysType;
  switch (myType) {
    case TableDataType.Boolean: sysType = typeof(bool); break;
    case TableDataType.Character: sysType = typeof(char); break;
    case TableDataType.DateTime: sysType = typeof(DateTime); break;
    case TableDataType.Integer: sysType = typeof(Int32); break;
    case TableDataType.Decimal: sysType = typeof(Decimal); break;
    case TableDataType.String: sysType = typeof(string); break;
    default: throw new ArgumentOutOfRangeException(string.Format("Data Type '{0}' is not allowed.", cd.DataType));
  }
  return sysType;
}

问题来自于在我的代码中不止一个位置使用与这些类似的例程。如果我告诉 DataGridViewColumn 它的格式为 Int32,然后向其传递 Integer,我会收到 ArgumentException 错误.

我正在寻找一个好的、快速的类包装器,它可以巧妙地存储值和一系列可接受的数据类型。

[编辑]我想出的解决方案:

使用 harpo 中提供的信息的评论和Bas的解决方案,我创建了这个类:

public static class Enumerate {

  private Enumerate() {
    throw new NotSupportedException();
  }

  public static SqlDbType ForSqlCe(System.Type item) {
    return sqlDbCode(item);
  }

  public static SqlDbType ForSqlCe(TableDataType item) {
    return sqlDbCode(item.GetType());
  }

  static SqlDbType sqlDbCode(System.Type item) {
    switch (Type.GetTypeCode(item)) {
      case TypeCode.Boolean: return SqlDbType.Bit;
      case TypeCode.Byte:
      case TypeCode.Char:
      case TypeCode.SByte: return SqlDbType.NChar;
      case TypeCode.DateTime: return SqlDbType.DateTime;
      case TypeCode.Decimal:
      case TypeCode.Double:
      case TypeCode.Single: return SqlDbType.Decimal;
      case TypeCode.Int16:
      case TypeCode.Int32:
      case TypeCode.Int64:
      case TypeCode.UInt16:
      case TypeCode.UInt32:
      case TypeCode.UInt64: return SqlDbType.Int;
      case TypeCode.String: return SqlDbType.NVarChar;
      case TypeCode.DBNull:
      case TypeCode.Empty:
      case TypeCode.Object:
      default: throw new TypeAccessException(item + " unknown");
    }
  }

  public static TableDataType ForTableData(SqlDbType item) {
    return tableDataCode(item.GetType());
  }

  public static TableDataType ForTableData(System.Type item) {
    return tableDataCode(item);
  }

  static TableDataType tableDataCode(System.Type item) {
    switch (Type.GetTypeCode(item)) {
      case TypeCode.Boolean: return TableDataType.Boolean;
      case TypeCode.Byte:
      case TypeCode.Char:
      case TypeCode.SByte: return TableDataType.Character;
      case TypeCode.DateTime: return TableDataType.DateTime;
      case TypeCode.Decimal:
      case TypeCode.Double:
      case TypeCode.Single: return TableDataType.Decimal;
      case TypeCode.Int16:
      case TypeCode.Int32:
      case TypeCode.Int64:
      case TypeCode.UInt16:
      case TypeCode.UInt32:
      case TypeCode.UInt64: return TableDataType.Integer;
      case TypeCode.String: return TableDataType.String;
      case TypeCode.DBNull:
      case TypeCode.Empty:
      case TypeCode.Object:
      default: throw new TypeAccessException(item + " unknown");
    }
  }

  public static Type ForWin32(string item) {
    string text = item.Trim().ToLower();
    switch (text) {
      case "boolean":
      case "bool":
      case "bit": return typeof(bool);
      case "byte":
      case "char":
      case "sbyte": return typeof(char);
      case "date":
      case "datetime":
      case "time": return typeof(DateTime);
      case "decimal":
      case "double":
      case "numeric":
      case "single": return typeof(Double);
      case "int":
      case "int16":
      case "int32":
      case "int64":
      case "integer":
      case "uint16":
      case "uint32":
      case "uint64": return typeof(Int32);
      case "string": return typeof(string);
      default:
        throw new TypeAccessException(item + " unknown");
    }
  }

  public static Type ForWin32(SqlDbType item) {
    return win32Code(item.GetType());
  }

  public static Type ForWin32(TableDataType item) {
    return win32Code(item.GetType());
  }

  static Type win32Code(System.Type item) {
    switch (Type.GetTypeCode(item)) {
      case TypeCode.Boolean: return typeof(bool);
      case TypeCode.Byte:
      case TypeCode.Char:
      case TypeCode.SByte: return typeof(char);
      case TypeCode.DateTime: return typeof(DateTime);
      case TypeCode.Decimal:
      case TypeCode.Double:
      case TypeCode.Single: return typeof(Decimal);
      case TypeCode.Int16:
      case TypeCode.Int32:
      case TypeCode.Int64:
      case TypeCode.UInt16:
      case TypeCode.UInt32:
      case TypeCode.UInt64: return typeof(Int32);
      case TypeCode.String: return typeof(string);
      case TypeCode.DBNull:
      case TypeCode.Empty:
      case TypeCode.Object:
      default: throw new TypeAccessException(item + " unknown");
    }
  }

}

最佳答案

如果您不想使用System.TypeCodeharpo建议,使用Type.GetType() :

string assemblyQualifiedName = "System.{0}, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";

string typeString = myEnumValue.ToString();
Type type = Type.GetType(string.Format(assemblyQualifiedName, typeString));

另一个选项是将映射存储在字典中:

static class TypeResolver
{
    static Dictionary<TableDataType, Type> typeLookup = new Dictionary<TableDataType, Type>();

    static TypeResolver()
    {
        typeLookup.Add(TableDataType.Integer, typeof(Int32));
        typeLookup.Add(TableDataType.String, typeof(String));
    }

    public static Type Resolve(TableDataType tableType)
    {
        return typeLookup[tableType];
    }
}

关于C#:返回系统数据类型的聪明助手类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6684667/

相关文章:

c# - ORA-08103 程序错误

c# - ASP.NET Core 路由中间件将租户名称放在 url 中

c# - .NET Core 2.0 中 PropertyInfo.IsPublic 的等价物

C# 接收 TCP/IP 多套接字服务器

c# - 执行反序列化时无法发现程序集异常

c# - 如何在 Angular 2 中序列化/反序列化 .NET 类型的 JSON

c# - 如何在我的应用程序中使用 lame.exe?

C# 从文本文件中的公钥获取 CngKey 对象

c# - 在 c# .net 中对服务结果进行正确的空检查

c# - 增强 C# 语法糖(或绕过 "Cannot use ref or out parameter")