public string GetClassName (Type type) {
if (type == null) {
throw new ArugmentNullException ("type");
}
if (!type.IsSubclassOf (typeof (UpnpObject)) &&
type != typeof (UpnpObject)) {
throw new ArgumentException (
"The type does not derive from UpnpObject.",
"type");
}
// do stuff with 'type'
}
if (type == null) {
throw new ArugmentNullException ("type");
}
if (!type.IsSubclassOf (typeof (UpnpObject)) &&
type != typeof (UpnpObject)) {
throw new ArgumentException (
"The type does not derive from UpnpObject.",
"type");
}
// do stuff with 'type'
}
It then occurred to me that I can do the same thing with a generic type parameter, but get all the checks for free!
public string GetClassName<T> () where T : UpnpObject {
//do stuff with 'typeof (T)'
}
//do stuff with 'typeof (T)'
}
Tada! Using generic type parameters as method parameters is nothing new (Aaron has something like this in the Banshee service stack), but the really neat thing is that you can use the generic constraints as a kind of argument pre-condition. If you have a method which takes a Type, consider using a generic type parameter rather than a method parameter. It guarantees that 'null' cannot be passed and it allows you to specify ancestry, interfaces, ref/value types, and the presence of a default constructor.
2 comments:
Works great, until you only have the type at runtime (perhaps you loaded it as a string from a configuration file). You'd still need the original version to cover many many scenarios.
Agreed with #1 -- any time you do anything interesting with generics, you do them with System.Reflection and have generics as a wrapper. At some point you'll deal with inheritance and have to use GetType().
Post a Comment