1

我有一个类,BaseClass它有一个GetPropertyByDataMemberName方法。此方法使用反射来获取具有DataMemberAttribute指定名称的属性。我想将它定义为一个静态方法,BaseClass所以我不必在每个子类中定义它。

问题是,由于此方法使用反射来查找属性,因此我需要以Type某种方式获取当前值才能调用GetProperties. 由于它是一个静态方法,我不能调用GetType,所以我不知道该怎么做!

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);
    }
}

为什么不让它成为非静态的?好吧,假设我有一个这样的子类:

class SubClassOne : BaseClass
{
    [DataMember(Name = "p2")]
    public string PropertyTwo { get; set; }
}

我希望能够做这样的事情:

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
}

我试过 make GetPropertyByDataMemberNameuse typeof(BaseClass),但它只获取 的属性BaseClass,而不是任何子类。

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);
}

那么,如何做到这一点呢?

4

2 回答 2

1

您可以使用泛型来实现这一点:

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);
}

你可以这样称呼它:

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
}
于 2013-02-05T15:52:55.703 回答
0

尝试这个:

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);
}
于 2013-02-05T16:04:31.917 回答