I have a class, BaseClass, that has a GetPropertyByDataMemberName method. This method uses reflection to get the property that has a DataMemberAttribute with a specified name. I want to define it as a static method in BaseClass so I don’t have to define it in each subclass.
Problem is, since this method uses reflection to look up the properties, I need to get the current Type somehow in order to call GetProperties. Since it’s a static method, I can’t call GetType, so I’m at a loss of how to do that!
abstract class BaseClass
{
[DataMember(Name = "p1")]
public int PropertyOne{ get; set; }
public static PropertyInfo GetPropertyByDataMemberName(string dataMemberName)
{
return GetType() // argh! can't call this statically!
.GetProperties()
.Where(z => Attribute.IsDefined(z, typeof(DataMemberAttribute)))
.Single(z => ((DataMemberAttribute)Attribute.GetCustomAttribute(z, typeof(DataMemberAttribute))).Name == dataMemberName);
}
}
Why not make it non-static? Well, let’s say I have a subclass like this:
class SubClassOne : BaseClass
{
[DataMember(Name = "p2")]
public string PropertyTwo { get; set; }
}
I want to be able to do something like this:
static void Main(string[] args)
{
// print property names
Console.WriteLine(BaseClass.GetPropertyByDataMemberName("p1").Name); // should work
Console.WriteLine(BaseClass.GetPropertyByDataMemberName("p2").Name); // should not work
Console.WriteLine(SubClassOne.GetPropertyByDataMemberName("p1").Name); // should work
Console.WriteLine(SubClassOne.GetPropertyByDataMemberName("p2").Name); // should work
}
I’ve tried making GetPropertyByDataMemberName use typeof(BaseClass), but that only gets the properties of BaseClass, not any of the subclasses.
public static PropertyInfo GetPropertyByDataMemberName(string dataMemberName)
{
return typeof(BaseClass)
.GetProperties() // only gets properties of BaseClass
.Where(z => Attribute.IsDefined(z, typeof(DataMemberAttribute)))
.Single(z => ((DataMemberAttribute)Attribute.GetCustomAttribute(z, typeof(DataMemberAttribute))).Name == dataMemberName);
}
So, how to do this?
You can use generics to achieve this:
You would call it like this: