簡體   English   中英

如何實現只能設置一次的屬性

[英]How to implement properties which can be set only one time

我想實現一些只能設置一次的屬性。 我知道readonly但我希望能夠從課外設置值。

情況如下:我有一個類,我用它作為從數據庫讀取的一些數據的鍵。 此密鑰類包含多個屬性。

我的第一個想法是創建多個構造函數,我可以像我需要的那樣設置屬性,但由於“not set”是大多數這些屬性的有效狀態,我很快就有了一堆構造函數,我認為這不是最好的方法。

我無法使用公共設置器制作屬性,因為它們是關鍵信息,之后更改它們也沒有用。 所以我需要一種方法從key-class外面設置一次,因為我不想為每種情況制作20個稍微不同的構造函數。

是否有一些像readonly一樣容易去做的方法或者我必須自己實現它?

正如@Fildor所評論的那樣, Builder模式可能適用於此處。 您可以根據需要隨時在構建器類上設置屬性,允許在那里進行多次分配沒有任何害處。 但是一旦你用它來構建你的類,那么它就被鎖定了,然后就不再允許修改了。

class MyClass {
  internal MyClass(MyClassBuilder builder) {
     MyProp1 = builder.MyProp1;
     MyProp2 = builder.MyProp2;
     MyProp3 = builder.MyProp3;
  }
  public string MyProp1 { get; }
  public string MyProp2 { get; }
  public string MyProp3 { get; }
}

class MyClassBuilder {
  public string MyProp1 { get; set; }
  public string MyProp2 { get; set; }
  public string MyProp3 { get; set; }
  public MyClass Build() => new MyClass(this);
}

用法: new MyClassBuilder { MyProp2 = "abc" }.Build() 基於相同的一般想法,也可以使用不同的API。

hvd的構建器模式非常好,它是您最有可能使用的。 不過,這是我的2美分。 我有時喜歡JS如何工作,在這里我嘗試模仿它。 這基本上是使用字典作為配置集合,包含屬性的名稱和所需的值。

public class Key
{
    private readonly string Property1;
    private readonly string Property2;
    private readonly string Property3 = "!";

    public Key(Dictionary<string, object> config)
    {
        if (config == null)
        {
            return;
        }

        var type = typeof(Key);
        var fields = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
        foreach (string name in config.Keys)
        {
            var field = fields.Where(f => f.Name == name).SingleOrDefault();
            if (field == null)
            {
                continue;
            }

            field.SetValue(this, config[name]);
        }
    }

    public string GetValues()
    {
        return Property1 + Property2 + Property3;
    }
}

你可以用它作為:

var key = new Key(new Dictionary<string, object>()
    {
        { "Property1", "Hi, " },
        { "Property2", "There" }
    }
);

Console.WriteLine(key.GetValues()); // Hi, There!

解決這個問題的一種方法是使用公共setter的屬性並為每個屬性設置一個標志,第一次將setter稱為set flag為true並通過檢查后續調用中的標志從setter返回。

如果您有太多屬性,請使用字典,而不是將屬性映射到狀態(設置/取消設置)。

嘗試這樣的事情(基本上是@SelmanGenc建議的):

public class Key {

private ConcurrentDictionary<string, bool> _setProps = new ConcurrentDictionary<string, bool>();
private string _prop1;

public string Prop1 {

get { return _prop1; }
set { 
    if(!_setProps.ContainsKey(nameof(Prop1)){
        _setProps.Add(nameof(Prop1), true);
        _prop1 = value;
    }
  }
 }
}

有私人財產,知道它是否已設置? 就像是:

public class MyClass
{
   private bool myValueSet = false;
   private string _myValue;

   public string MyValue
   {
      set {
        if (!myValueSet)
        {
          _myValue = value;
        }
      }
      get {
        return _myValue; 
      }
   }
}

暫無
暫無

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

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