簡體   English   中英

為什么屬性的屬性必須是可讀的?

[英]Why do properties of attributes have to be readable?

請考慮以下屬性。

internal class NiceAttribute : Attribute
{
  private string _stuff;

  public string Stuff
  {
    set { _stuff = value; }
  }
}

當我嘗試使用屬性[Nice(Stuff = "test")] ,編譯器會出現以下錯誤。

'Stuff'不是有效的命名屬性參數。 命名屬性參數必須是非readonly,static或const的字段,或者是公共而非靜態的讀寫屬性。

要求財產具有可讀性的理由是什么?


更新
我將嘗試繪制我的用例,以便在屬性上具有只寫屬性。

interface ISettingsBuilder
{
  Settings GetSettings();
}

class SettingsAttribute : Attribute, ISettingsBuilder
{
  private readonly IDictionary<string, object> _settings =
    new Dictionary<string, object>();

  public Settings GetSettings()
  {
    // Use _settings to create an immutable instance of Settings
  }

  public string Stuff
  {
    set { _settings["Stuff"] = value; }
  }

  // More properties ...
}

ISettingsBuilder可能還有其他實現。 例如,提供一個很好的API來通過代碼構建設置。

我最終通過拋出NotImplementedException實現我的getter。

  public string Stuff
  {
    get { throw new NotImplementedException(); }
    set { _settings["Stuff"] = value; }
  }

你能想出一個更好的方法來做這樣的事嗎?

我懷疑編譯器使用了一個稍微誤導的檢查,看看你是否在這里訪問私人財產

編輯 “我們”現在已找到實際來源。 出於提供信息的目的,這里有完整的細分,但請隨時跳到底部。
(注意應該如何針對Mono編譯器提交bug。我會認為這個問題已經過了一段時間)

編譯器錯誤CS0617

'reference'不是有效的命名屬性參數。 命名屬性參數必須是非readonly,static或const的字段,或非靜態的讀寫屬性。

嘗試訪問屬性類的私有成員。

似乎它正在使用某種查找(類似於反射)來確保getter可訪問的 ,如果不是,則斷定它必須是私有的

其中,當然,它不需要是:)

單聲道兼容性:

為了好玩,請注意單聲道編譯器在接受此屬性時沒有任何問題: https//ideone.com/45fCX

因為反思:

當然,可能是編譯器要求屬性參數具有可反映的值。 如果屬性不是公開可讀的,則只能使用反射來“觀察”屬性存在,而不是使用它初始化的參數。

我不確切地知道, 為什么會有這樣的設計選擇,但如果考慮到反射的使用,它確實有意義。

更新 @Arun發布了確認此猜想的相關引用(謝謝!):

通過反射訪問屬性一旦屬性與程序元素相關聯,就可以使用反射來查詢它們的存在和值。 查詢屬性的主要反射方法包含在System.Reflection.MemberInfo類(GetCustomAttributes方法系列)中。

原因必須是: 屬性參數必須具有可反射的值

獎項問題:如何處理位置參數? 如何反映這些?

此鏈接是Visual Studio 2003的參考,但我想它幾乎沒有改變。

該鏈接的相關部分:

通過反射訪問屬性一旦屬性與程序元素相關聯,就可以使用反射來查詢它們的存在和值。 查詢屬性的主要反射方法包含在System.Reflection.MemberInfo類(GetCustomAttributes方法系列)中。

暫無
暫無

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

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