下面的代码循环遍历字符串字典和IMyCompanySettings,寻找实现IMyCompanyProductSetting的值.显然,尝试强制转换异常是一种非常昂贵的方法.
public static ListGetProductSettings(ConfigurationManager cfm) { List ret = new List (); foreach(IMyCompanySetting setting in cfm.Values) { try { IMyCompanyProductSetting prod = (IMyCompanyProductSetting)setting; ret.Add(prod); } catch { // Do nothing. } } return ret; }
有什么更好的方法呢?
使用[object] is [interface/class]
表达式:
if (setting is IMyCompanyProductSetting) { ... }
或者,你可以使用as
试图转换对象的关键字,如果它失败,它将返回而不是抛出异常null
.请注意,目标类型必须是as
关键字中的引用类型:
var prod = setting as IMyCompanyProductSetting; if (prod != null) { ... }
您应该始终使用上面的代码而不是等效的异常处理.
IEnumerable
类型(LINQy):正如Jon Skeet指出的那样,您应该使用OfType
扩展方法轻松过滤序列(假设您有LINQ):
var filteredSequence = sequence.OfType();
IEnumerable
为类型(LINQy):如果要尝试将每个元素转换为目标类型(而不是按类型过滤),则可以使用Cast
扩展方法:
var castedSequence = sequence.Cast();
"硬"方式(LINQ之前)是使用"as".这比使用"is"然后每次转换(因为"是"和转换需要执行时间检查)更有效:
IMyCompanyProductSetting prod = setting as IMyCompanyProductSetting; if (prod != null) { ret.Add(prod); }
有关何时使用"as"以及何时使用演员表,请参阅另一个问题.
但是,如果您使用的是.NET 3.5,则非常简单:
return cfm.Values.OfType().ToList();
很容易 :)