簡體   English   中英

C#如何獲取正在設置的屬性的名稱

[英]C# How to get the name of the property being set

我有一個數據庫對象類,做了一堆繁重的工作。 然后,我擴展該對象並構建表示要修改的實際對象和字段的類。 它基本上看起來像這樣:

public class MyObject : DatabaseObject
{
    public string FieldX
    {
        get { return GetValue<string>("FieldX"); }
        set { SetValue<string>("FieldX", value); }
    }

    public int FieldY
    {
        get { return GetValue<int>("FieldY"); }
        set { SetValue<int>("FieldY", value); }
    }
}

public class DatabaseObject
{
    public T GetValue<T>(string FieldName)
    {
         // Code that actually gets the right value
    }

    public void SetValue<T>(string FieldName, T value)
    {
         // Code that actually sets the value in the right place
    }
}

這樣,我以后可以實例化MyObject並開始通過代碼設置屬性。 我們的想法是生成更簡單,更易於維護的代碼。

它在實踐中很有效。 但是,我注意到MyObject的代碼非常重復。 例如,使用FieldX,我最終在get / set中指定了“string”類型,並且還必須在get / set中指定屬性名稱“FieldX”。

我想知道是否有辦法進一步簡化代碼以減少重復。

我知道我可以使用反射:

MethodBase.GetCurrentMethod().Name.Substring(4)

...在get / set調用中獲取屬性名稱,我可以使用GetType()來獲取set時的值類型,但理想情況下我想從基本GetValue /中獲取原始屬性名稱SetValue方法(理想情況下不解析堆棧跟蹤)。

理想情況下,我正在尋找這樣的東西:

    public string FieldX
    {
        get { return GetValue(); }
        set { SetValue(value); }
    }

    public int FieldY
    {
        get { return GetValue(); }
        set { SetValue(value); }
    }

有什么想法嗎?

C#5.0通過在默認參數上使用[CallerMemberName]屬性來支持此功能。 像這樣的東西:

public static object GetValue([CallerMemberName] string caller = "")
{
    Trace.WriteLine("Called by: " + caller);
    return null;
}

並將使用如下:

public string FieldX
{
    get { return (string)GetValue(); }
}

這適用於編譯器根據調用者的名稱自動提供GetValue參數。

您可以在MSDN中了解有關此功能的更多信息。

您可以使GetValue通用,因此可以像屬性中的GetValue<string>()一樣使用它。

這比你想要的要長一些,但也可以使用(使用強類型的 lambda表達式)。

public class MyObject : DatabaseObject
{
    public string FieldX
    {
        get { return GetValue(() => FieldX); }
        set { SetValue(() => FieldX, value); }
    }

    public int FieldY
    {
        get { return GetValue(() => FieldY); }
        set { SetValue(() => FieldY, value); }
    }
}

public class DatabaseObject
{
    public T GetValue<T>(Expression<Func<T>> field)
    {
         string fieldName = GetFieldName(field);
         // Code that actually gets the right value
    }

    public void SetValue<T>(Expression<Func<T>> field, T value)
    {
         string fieldName = GetFieldName(field);
         // Code that actually sets the value in the right place
    }

    private static string GetFieldName<T>(Expression<Func<T>> field)
    {
        return ((MemberExpression)field.Body).Member.Name;
    }
}

暫無
暫無

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

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