C#:聪明的助手类返回系统数据类型 [英] C#: Clever Helper Class to return System Data Type
问题描述
我正与一个数据库,它是唯一能够支持我写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:sysType = 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屋!