Using “as bool?” instead of “object something = ViewState[”hi“]”
所以我在看旧代码(2.0),我发现了:
1 2 3 4 5 6 | object isReviewingValue = ViewState["IsReviewing"]; if (isReviewingValue is bool) { return (bool)isReviewingValue; } |
我的第一个想法是用"as"关键字来避免不需要的
1 | (bool)isReviewingValue; |
但是"as"只适用于非值类型。没问题,我就这么做了:
1 2 3 4 5 | bool? isReviewingValue= ViewState["IsReviewing"] as bool?; if (isReviewingValue.HasValue) { return isReviewingValue.Value; } |
问题是:除了看起来更易读之外,这真的更好吗?
编辑:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | public Stopwatch AsRun() { Stopwatch watch = new Stopwatch(); watch.Start(); for (Int32 loopCounter = 0; loopCounter < 10000; loopCounter++) { Object value = true; Boolean? test = value as Boolean?; if (test.HasValue) { Boolean something = test.Value; } } watch.Stop(); return watch; } public Stopwatch ObjectIsRun() { Stopwatch watch = new Stopwatch(); watch.Start(); for (Int32 loopCounter = 0; loopCounter < 10000; loopCounter++) { Object test = true; if (test is Boolean) { Boolean something = (Boolean)test; } } watch.Stop(); return watch; } |
答案:结果是,使用上述方法以测试的方式运行时,原始代码的速度大约快10倍。
coalesce操作符将为您删除一些代码。为了回答你的问题,正如吉米所说的,两者之间的技术差异很小,所以用你觉得更好的方法。就我个人而言,我倾向于使用这种方法。我可能会被认为有偏见,尽管…
1 2 3 4 | private bool GetIsReviewing() { return (ViewState["IsReviewing"] as bool?) ?? false; } |
我认为第一个更容易阅读,而且速度也更快(根据我刚刚运行的一个测试,大约10纳秒对100纳秒);(即不会以任何方式减慢程序速度)]
您可以使用一般的扩展方法来添加语法糖分:
1 2 3 4 5 6 7 8 9 | public static class TypecastExtensions { public static T CastOrDefault<T>(this object o) where T : struct { return o as Nullable<T> ?? default(T); } public static T CastOrDefault<T>(this object o, T defaultValue) where T : struct { return o as Nullable<T> ?? defaultValue; } } |
用途:
1 | bool isReviewingValue = ViewState["IsReviewing"].CastOrDefault<bool>(); |
如果在第一个示例中,您返回了空值,那么为什么不使用它:
1 2 3 4 | bool? MyMethod() { return ViewState["IsReviewing"] as bool?; } |
第二个更好,因为如果viewstate["isreviewing"]不是bool,那么关键字automatically会将其设置为空。在第一个选项中,你自己实现它,你不能这样做。结果在良好的容器中。
实际上情况更糟。如果"isreviewing"中的值不是bool或null,则代码将引发异常。原始版本将忽略它。