簡體   English   中英

如何在超類中定義靜態方法以使用反射獲取子類的屬性?

[英]How to define a static method in a superclass to get the properties of a subclass using reflection?

我有一個類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
}

我試過使GetPropertyByDataMemberName使用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);
}

那么,該怎么做呢?

您可以使用泛型來實現此目的:

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
}

嘗試這個:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM