Reputation: 22404
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?
Upvotes: 1
Views: 315
Reputation: 32541
Try this:
public static PropertyInfo GetPropertyByDataMemberName(string dataMemberName)
{
var st = new StackTrace();
var type = ((System.Reflection.MemberInfo)(st.GetFrame(0).GetMethod())).ReflectedType;
return type // argh! can't call this statically!
.GetProperties()
.Where(z => Attribute.IsDefined(z, typeof(DataMemberAttribute)))
.Single(z => ((DataMemberAttribute)Attribute
.GetCustomAttribute(z, typeof(DataMemberAttribute))).Name == dataMemberName);
}
Upvotes: 0
Reputation: 174299
You can use generics to achieve this:
public static PropertyInfo GetPropertyByDataMemberName<T>(string dataMemberName)
where T : BaseClass
{
return typeof(T)
.GetProperties()
.Where(z => Attribute.IsDefined(z, typeof(DataMemberAttribute)))
.Single(z => ((DataMemberAttribute)Attribute.GetCustomAttribute(z, typeof(DataMemberAttribute))).Name == dataMemberName);
}
// Shortcut overload for properties on BaseClass.
public static PropertyInfo GetPropertyByDataMemberName(string dataMemberName)
{
return GetPropertyByDataMemberName<BaseClass>(dataMemberName);
}
You would call it like this:
static void Main(string[] args)
{
Console.WriteLine(BaseClass.GetPropertyByDataMemberName("p1").Name); // should work
Console.WriteLine(BaseClass.GetPropertyByDataMemberName("p2").Name); // should not work
Console.WriteLine(BaseClass.GetPropertyByDataMemberName<SubClassOne>("p1").Name); // should work
Console.WriteLine(BaseClass.GetPropertyByDataMemberName<SubClassOne>("p2").Name); // should work
}
Upvotes: 1