The code below is looping through a dictionary of strings and IMyCompanySettings looking for values that implement IMyCompanyProductSetting. Clearly, trying to cast and raising an exception is a very expensive way to do this.
public static List<IMyCompanyProductSetting> GetProductSettings(ConfigurationManager cfm)
{
List<IMyCompanyProductSetting> ret = new List<IMyCompanyProductSetting>();
foreach(IMyCompanySetting setting in cfm.Values)
{
try
{
IMyCompanyProductSetting prod = (IMyCompanyProductSetting)setting;
ret.Add(prod);
}
catch
{
// Do nothing.
}
}
return ret;
}
What's a better way to do this?
Use [object] is [interface/class]
expression:
if (setting is IMyCompanyProductSetting) {
...
}
Alternatively you can use the as
keyword which tries to cast the object and if it fails, instead of throwing exception, it'll return null
. Note that the target type must be a reference type in the as
keyword:
var prod = setting as IMyCompanyProductSetting;
if (prod != null) {
...
}
You should always use the above code instead of the equivalent exception handling.
IEnumerable
by type (LINQy):As Jon Skeet pointed out, you should use OfType
extension method to filter a sequence easily (assuming you got LINQ):
var filteredSequence = sequence.OfType<TargetType>();
IEnumerable
to type (LINQy):If you want to try casting each element to the target type (as opposed to filtering by type), you can use the Cast
extension method:
var castedSequence = sequence.Cast<TargetType>();
The "hard" way (pre-LINQ) is to use "as". This is more efficient than using "is" and then casting each time (as both the "is" and the cast require execution-time checks):
IMyCompanyProductSetting prod = setting as IMyCompanyProductSetting;
if (prod != null)
{
ret.Add(prod);
}
See another question for when to use "as" and when to use a cast.
If you're using .NET 3.5, however, it's really easy:
return cfm.Values.OfType<IMyCompanyProductSetting>().ToList();
Very easy :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With