OK, I’m ashamed this extension method took me this long to think of. It is the first extension method that I’ve created that warrants extending Object as well. But the fact that it doesn’t exist makes me think there might be a reason for that as well (shrugs).
1: public static T CastOrDefault<T>(this System.Object o)
2: {
3: if (o == null) return default(T);
4:
5: if (o is T)
6: {
7: return (T) o;
8: }
9: else
10: {
11: return default(T);
12: }
13: }
This method is a blood brother to FirstOrDefault. FirstOrDefault extends IEnumerable to return the first item in the list, or if there is nothing in the list, it returns the default value (often null).
This is CastOrDefault. It casts an object or returns the default value if it can’t.
Uses: in my current application I have to deal with a lot of lists that return base types (Component, object, Control, etc) and I need them more specific. So I end up writing the same block over and over to check if the object is null, if I can cast it, then cast the object, and return it. That code is now gone.
Here is a trivial example for when you know the name of object at runtime, but not at design time:
1: private Label GetLabel(string name)
2: {
3: return this.Controls[name].CastOrDefualt<Label>();
4: }
Except for structs what is different with just using as?
1: private Label GetLabel(string name)
2: {
3: return this.Controls[name] as Label;
4: }
Mainly that it does work with Struts.
Here is another example. You are loading a TreeView, every tree node has it’s tag set to a number. You catch the AfterSelect event and do this:
private void BuildingStructureTreeView_AfterSelect(object sender, TreeViewEventArgs e)
{
var value = e.Node.Tag.CastOrDefault());
}
That said, the “as ” will work for most cases.