Aug 24 2009

CastAs() Extension Method. Should It Stay Or Should It Go?

Have you ever coded something like this…

((Class1)((Class2)item).AProperty().AMethod()

Ok, I don’t mean the names (hopefully you’ve never used those), but doing multiple inline casts. It’s not pretty for sure. My guess is you had to read the example a few times to realize what it was doing. Last night I was kicking around an extension method to clean this up some. Here’s what I came up with…

public static T CastAs<T>(this object item)
{
  return (T)item;
}

Impressive, eh? Now the original example can be rewritten like this…

item.CastAs<Class2>().AProperty.CastAs<Class1>().AMethod()

Still not what I’d call beautiful code, but I bet you could figure out what it was doing the first time you read it, no? However, there’s one down side. In the original example if I had tried to do something like this…

int item;
((Class1)((Class2)item).AProperty().AMethod()

…I would get a nice compiler warning letting me know that “int” can’t be cast as a “Class2″. Using the CastAs extension method, that nice compiler warning turns into a nasty runtime bug. So the question for you, dear reader, is, is CastAs a good idea or a bad idea? (and the second question is, is, “is, is” valid english?)

For me, I actually ended up taking it back out for now. Instead, I rewrote the original example as…

Class2 class2 = (Class2)item;
Class1 class1 = (Class1)class2.AProperty();
class1.AMethod()

What are your thoughts?

  • Share/Save/Bookmark

Aug 16 2009

Enum.GetValues() for Silverlight

I ran into a problem the other day using enums in Silverlight. I needed a way to enumerate all the valid values in an enum. In the standard CLR I would use Enum.GetValues, but it turns out that function isn’t provided in Silverlight. So, I did a little decompiling and found that the standard CLR uses some simple reflection in the guts of GetValues. Armed with that knowledge, I created this helper function.


public static IEnumerable<T> GetEnumValues<T>()
{
  Type type = typeof(T);

  if (!type.IsEnum)
  {
    throw new Exception("{0} is not an enum.", type.FullName);
  }

  FieldInfo[] fields =
      type.GetFields(BindingFlags.Public | BindingFlags.Static);

  foreach (var item in fields)
  {
    yield return (T)item.GetValue(null);
  }
}

Using this function is pretty straight forward. It might look something like this…


foreach (var item in GetEnumValues<MyEnum>())
{
  //do stuff here
}
  • Share/Save/Bookmark