簡體   English   中英

屬性和命名/可選構造函數參數不起作用

[英]Attributes and Named/Optional constructor parameters not working

我有自定義屬性,如下所示:

  [AttributeUsage(AttributeTargets.Field)]
  public class EnumDisplayAttribute : Attribute
  {
    public string Description { get; private set; }
    public string Code { get; private set; }

    public EnumDisplayAttribute(string description = null, string code = null)
    {
      Description = description;
      Code = code;
    }
  }

兩個構造函數參數都是可選的。

在像這樣的字段上使用此屬性時

  public enum TransactionType
  {
    [EnumDisplay(code: "B")] 
    Bill,
    [EnumDisplay(description: null, code: "C")]
    CashReceipt,
  }

我沒有在代碼編輯器中看到任何波形,但我看到一個模糊的錯誤,沒有任何文件行號列。 錯誤消息是:

錯誤CS0182:屬性參數必須是屬性參數類型的常量表達式,typeof表達式或數組創建表達式

單擊該錯誤不會執行任何操作。 也就是說,您不會導航到錯誤站點(顯然,因為沒有行號和列)。

即使我像這樣設置屬性:

[EnumDisplay("This is a Bill")] 

編譯器不喜歡它。

實際上,我被迫提供兩個參數(已命名或未命名),以便將此屬性用作屬性。

當然,如果我將此屬性用作常規類,如下所示:

var enumDisplayAttribute = new EnumDisplayAttribute();
enumDisplayAttribute = new EnumDisplayAttribute(description: "This is a Bill");
enumDisplayAttribute = new EnumDisplayAttribute(code: "B");
enumDisplayAttribute = new EnumDisplayAttribute(description: "This is a Bill", code: "B");
enumDisplayAttribute = new EnumDisplayAttribute("This is a Bill", "B");
enumDisplayAttribute = new EnumDisplayAttribute("This is a Bill");

編譯器將接受上述任何一種“樣式”。

當然,我失去了一些東西,或者我的大腦不能正常工作。

在C#中已存在的屬性的可選值之后,可選參數被添加到C#中。 因此,對於可選的屬性參數,您應該回退到特定於屬性的語法:

[AttributeUsage(AttributeTargets.Field)]
public class EnumDisplayAttribute : Attribute
{
    public string Description { get; set; }
    public string Code { get; set; }

    public EnumDisplayAttribute()
    {
    }
}

public enum TransactionType
{
    [EnumDisplay(Code = "B")] 
    Bill,
    [EnumDisplay(Description = null, Code = "C")]
    CashReceipt,
}

如您所見,最終結果實際上是相同的,但不是使用命名參數,而是使用命名屬性(其中[EnumDisplay(Description = null, Code = "C")]等語法只能在屬性聲明中使用) 。

想起來的另一種方式是,屬性聲明“借用”從方法/構造函數調用它的語法,而是屬性聲明本身不是方法調用,所以他們沒有得到所有相同的功能的方法。

如果您確實希望使用構造函數將值推送到屬性中(例如,如果某些屬性的屬性是必需的,或者對它們執行某種處理),您可以隨時上學並重載構造函數。

例如:

[AttributeUsage(AttributeTargets.Field)]
public class SampleAttribute : Attribute
{
    public string MandatoryProperty { get; private set; }
    public string OptionalProperty { get; private set; }

    // we use an overload here instead of optional parameters because 
    // C# does not currently support optional constructor parameters in attributes
    public SampleAttribute(string mandatoryProperty)
        : this(mandatoryProperty, null)
    {
    }

    public SampleAttribute(string mandatoryProperty, string optionalProperty)
    {
        MandatoryProperty = mandatoryProperty;
        OptionalProperty = optionalProperty;
    }
}

可選參數實際上不是可選的,方法簽名中包含所有參數,屬性是特殊的(存在於可選參數之前,並且當作為屬性應用時具有不同的規則(例如,考慮誰調用屬性構造函數))。 但我想,將來會增加支持。

目前,如果您希望實現可選效果,請嘗試以下操作:

[AttributeUsage(AttributeTargets.Field)]
public class EnumDisplayAttribute : Attribute
{
  public string Description { get; set; }
  public string Code { get; set; }

}

並按原樣申請:

[EnumDisplay(Description = null, Code = "C")]
private object _aField;

暫無
暫無

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

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