我们从DataRow
做了很多打包和解包。是的,我们应该使用ORM,但在此之前,这就是我们所拥有的。作为这样的结果,有很多的代码看起来像这样:是否有更具有泛型的方式来执行此类行为?
string username;
var temp = dr["Username"];
if (DbNull.Equals (temp))
{
username = "Anonymous";
} else {
username = dr["Username"].ToString();
}
最终,这成为一个模式,被翻译成辅助方法:
string username = StringExtensions.SafeParse (dr["Username"], "Anonymous");
这仍然繁琐,而且所有类型的基元都需要扩展方法。它也混淆了代码。我在object
上创建了一个通用扩展方法,名为As<T>
。用法是这样的:
string username = dr["Username"].As<string> ("Anonymous");
这种相对简单的变化已经达到泰然自若地与其他开发者,并在地方有很多的习惯。我不满意的部分是潜在的性能影响。 现在,我知道没有过早优化。我绝对编写了代码,没有任何过早的优化,并且它的封装足够,以后优化它不应该是一个大问题。我已经对该方法进行了基准测试,以在相对适中的2GHz工作站上每秒执行大约250万次转换,而且我必须承认,与节省其他开发人员和提高可读性的时间相比,这是惊人的性能。但是,考虑到下面的代码示例,我觉得我滥用语言功能,并且可以做得更好。该方法与“HERE BE DRAGONS”xmldoc'ed大声哭泣!我正在寻找更好的方法来避免双重拳击。为简洁起见,我省略的实际版本在许多情况下实际使用TryParse
。
public static TDestination As<TDestination> (this object source, TDestination defaultValue = default(TDestination))
{
if (source is TDestination)
return (TDestination) source;
if (source == null || DbNull.Equals(source))
return defaultValue;
if (TDestination is int)
return (TDestination) (object) Convert.ToInt32 (source.ToString());
if (TDestination is long)
return (TDestination) (object) Convert.ToInt64 (source.ToString());
if (TDestination is short)
return (TDestination) (object) Convert.ToInt16 (source.ToString());
// and so on...
}
你的'As'代码示例不能编译。 –
phoog