C#:聪明的助手类返回系统数据类型 [英] C#: Clever Helper Class to return System Data Type

查看:124
本文介绍了C#:聪明的助手类返回系统数据类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正与一个数据库,它是唯一能够支持我写code的数据类型。

我创建了一个枚举参数,可用类型的列表。

 公开枚举TableDataType
{
  无= 0,字符串= 1,整数= 2,字符= 3,布尔= 4,日期时间= 5,小数= 6
}
 

这工作,但我还是要处理进入和回来了我的数据结构:

  TableDataType GetMyType(COL的DataGridViewColumn){
  TableDataType类型;
  如果(col.ValueType == typeof运算(布尔)){
    TYPE = TableDataType.Boolean;
  }否则,如果(col.ValueType == typeof运算(炭)){
    TYPE = TableDataType.Character;
  }否则,如果(col.ValueType == typeof运算(日期时间)){
    TYPE = TableDataType.DateTime;
  }否则,如果(col.ValueType == typeof运算(十进制)){
    TYPE = TableDataType.Decimal;
  }否则,如果(col.ValueType == typeof运算(的Int32)){
    TYPE = TableDataType.Integer;
  }否则,如果(col.ValueType == typeof运算(字符串)){
    TYPE = TableDataType.String;
  } 其他 {
    抛出新的ArgumentException(的String.Format(数据类型{0}不支持,col.ValueType));
  }
  返回类型;
}
 

再有就是code走另一条路......

 键入GetSystemType(TableDataType的myType){
  键入sysType;
  开关(的myType){
    案例TableDataType.Boolean:s​​ysType = typeof运算(布尔);打破;
    案例TableDataType.Character:sysType = typeof运算(焦);打破;
    案例TableDataType.DateTime:sysType = typeof运算(日期时间);打破;
    案例TableDataType.Integer:sysType = typeof运算(Int32)已;打破;
    案例TableDataType.Decimal:sysType = typeof运算(十进制);打破;
    案例TableDataType.String:sysType = typeof运算(字符串);打破;
    默认:抛出新ArgumentOutOfRangeException(的String.Format(数据类型{0}是不允许的。,cd.DataType));
  }
  返回sysType;
}
 

这个问题是使用程序类似于这些在我的code以上的地方。如果我告诉一个的DataGridViewColumn ,它格式化为一个的Int32 然后通过它的整数,我得到的ArgumentException 错误。

我正在寻找一个好,速度快的类包装,巧妙地存储的价值和可接受的数据类型的选择范围。

解决方案,我想出了:

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

 公共静态类枚举{

  私人枚举(){
    抛出新NotSupportedException异常();
  }

  公共静态的SqlDbType ForSqlCe(System.Type的项目){
    返回SQLDB code(项目);
  }

  公共静态的SqlDbType ForSqlCe(TableDataType项目){
    返回SQLDB code(item.GetType());
  }

  静态的SqlDbType SQLDB code(System.Type的项目){
    开关(Type.GetType code(项目)){
      案件类型code.Boolean:返回SqlDbType.Bit;
      案件类型code.Byte:
      案件类型code.Char:
      案件类型code.SByte:返回SqlDbType.NChar;
      案件类型code.DateTime:返回SqlDbType.DateTime;
      案件类型code.Decimal:
      案件类型code.Double:
      案件类型code.Single:回报SqlDbType.Decimal;
      案件类型code.Int16:
      案件类型code.Int32:
      案件类型code.Int64:
      案件类型code.UInt16:
      案件类型code.UInt32:
      案件类型code.UInt64:返回SqlDbType.Int;
      案件类型code.String:返回SqlDbType.NVarChar;
      案件类型code.DBNull:
      案件类型code.Empty:
      案件类型code.Object:
      默认:抛出新TypeAccessException(项目+未知);
    }
  }

  公共静态TableDataType ForTableData(的SqlDbType项目){
    返回tableData code(item.GetType());
  }

  公共静态TableDataType ForTableData(System.Type的项目){
    返回tableData code(项目);
  }

  静态TableDataType tableData code(System.Type的项目){
    开关(Type.GetType code(项目)){
      案件类型code.Boolean:返回TableDataType.Boolean;
      案件类型code.Byte:
      案件类型code.Char:
      案件类型code.SByte:返回TableDataType.Character;
      案件类型code.DateTime:返回TableDataType.DateTime;
      案件类型code.Decimal:
      案件类型code.Double:
      案件类型code.Single:回报TableDataType.Decimal;
      案件类型code.Int16:
      案件类型code.Int32:
      案件类型code.Int64:
      案件类型code.UInt16:
      案件类型code.UInt32:
      案件类型code.UInt64:返回TableDataType.Integer;
      案件类型code.String:返回TableDataType.String;
      案件类型code.DBNull:
      案件类型code.Empty:
      案件类型code.Object:
      默认:抛出新TypeAccessException(项目+未知);
    }
  }

  公共静态类型ForWin32(字符串项){
    。字符串文本= item.Trim()TOLOWER();
    开关(文字){
      案布尔:
      案布尔:
      案位:返回的typeof(布尔);
      案字节:
      案字符:
      案为sbyte:返回的typeof(焦);
      案日期:
      案日期时间:
      案时间:返回的typeof(DateTime的);
      案十进制:
      案例双:
      案数字:
      案单:返回的typeof(双人间);
      案INT:
      案INT16:
      案INT32:
      案的Int64:
      案整数:
      案UINT16:
      案UINT32:
      案UINT64:返回的typeof(Int32)已;
      案串:返回的typeof(串);
      默认:
        抛出新TypeAccessException(项目+未知);
    }
  }

  公共静态类型ForWin32(的SqlDbType项目){
    返回的Win32 code(item.GetType());
  }

  公共静态类型ForWin32(TableDataType项目){
    返回的Win32 code(item.GetType());
  }

  静态类型的win32 code(System.Type的项目){
    开关(Type.GetType code(项目)){
      案件类型code.Boolean:返回的typeof(布尔);
      案件类型code.Byte:
      案件类型code.Char:
      案件类型code.SByte:返回的typeof(焦);
      案件类型code.DateTime:返回的typeof(DateTime的);
      案件类型code.Decimal:
      案件类型code.Double:
      案件类型code.Single:返回的typeof(十进制);
      案件类型code.Int16:
      案件类型code.Int32:
      案件类型code.Int64:
      案件类型code.UInt16:
      案件类型code.UInt32:
      案件类型code.UInt64:返回的typeof(Int32)已;
      案件类型code.String:返回的typeof(串);
      案件类型code.DBNull:
      案件类型code.Empty:
      案件类型code.Object:
      默认:抛出新TypeAccessException(项目+未知);
    }
  }

}
 

解决方案

如果你不想使用的 System.Type的code 哈波表明,使用 Type.GetType()

 字符串assemblyQualifiedName =系统{0},mscorlib程序,版本= 4.0.0.0,文化=中性公钥= b77a5c561934e089。

字符串typeString = myEnumValue.ToString();
类型类型= Type.GetType(的String.Format(assemblyQualifiedName,typeString));
 

另一种方法是存储在一个字典映射:

 静态类TypeResolver
{
    静态字典< TableDataType,类型> typeLookup =新字典< TableDataType,类型>();

    静态TypeResolver()
    {
        typeLookup.Add(TableDataType.Integer的typeof(的Int32));
        typeLookup.Add(TableDataType.String的typeof(字符串));
    }

    公共静态类型解析(TableDataType TABLETYPE)
    {
        返回typeLookup [TABLETYPE]
    }
}
 

I'm working with a database that is only capable of supporting data types that I have written code for.

I created an Enum parameter with a list of available types.

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

This works, but I still have to process going in and coming back out of my data structures:

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;
}

Then there is code going the other way...

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;
}

The problem comes from using routines similar to these at more than one spot in my code. If I tell a DataGridViewColumn that it is formatted for an Int32 then pass it an Integer, I get ArgumentException errors.

I'm looking for a good, fast class wrapper that cleverly stores the value and a select range of acceptable data types.

[EDIT] Solution I came up with:

Using the information provided in harpo's comment and Bas's solution, I created this class:

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");
    }
  }

}

解决方案

If you dont want to use System.TypeCode like harpo suggests, use 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));

Another option is to store the mapping in a Dictionary:

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#:聪明的助手类返回系统数据类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆