如何使用generics来处理需要仔细投射的返回值?
我有一些数据访问层代码调用存储过程并返回各种数据类型的标量值。 语法是ExecuteDecimal,ExecuteString等。我希望它是Execute
或Execute
我尝试这个实现,我无法编译,除非我正在使用“(T)值”进行转换,如果我尝试检查类型并调用方法进行转换,没有这样的运气。
更新的问题为什么我必须在转换为T之前转换为对象?
更新的代码
internal T Execute(string storedProcName, Hashtable parameters) { //Next lines do compile (thanks to suggestions from answers!) if (typeof(T) == typeof(string)) return (T) (object) ExecuteScalar(storedProcName, parameters).ToString(); else if (typeof(T) == typeof(int)) return (T)(object) Convert.ToInt32(ExecuteScalar(storedProcName, parameters)); //Next line compiles, but not all things boxed in an object can //be converted straight to type T (esp db return values that might contain DbNull.Value, etc) return (T)ExecuteScalar(storedProcName, parameters); }
试试这个:
var result = ExecuteScalar(storedProcName, parameters); if(Convert.IsDBNull(result)) return default(T); if(result is T) // just unbox return (T)result; else // convert return (T)Convert.ChangeType(result, typeof(T));
更新 :修复了DBNull处理
typeof(T) == typeof(string)
并针对DBNull.Value
进行空值检查
整体方法:
internal T Execute(string storedProcName, Hashtable parameters) { object res = ExecuteScalar(storedProcName, parameters); if (Convert.IsDBNull(res)) return default(T); //or handle somehow return (T)Convert.ChangeType(res, typeof(T)); }
试试’as’关键字
object o = ExecuteScalar(storedProcName, parameters); string s; int i; // .. more if ((s = o as string) != null) { return s; } if ((i = o as int?) != null) // can't use as for value types, so use nullable { return Convert.ToInt32(o); } return o as T;
也许您的函数可能会被更改为允许传递对象转换函数:
internal T Execute(string storedProcName, Hashtable parameters, Func
然后你可以为你知道的人创建重载:
internal string ExecuteForString(string storedProcName, Hashtable parameters) { return Execute(storedProcName, parameters, (o) => o.ToString()); } internal int ExecuteForInt(string storedProcName, Hashtable parameters) { return Execute(storedProcName, parameters, Convert.ToInt32); }
在你的DBNull检查的情况下,你可以返回default(T)
或者你可以添加另一个重载来传递一个默认值,如果返回DBNull – 例如在int的情况下,最好回到-1而不是0。