我应该使用set once变量吗?

Nif*_*fle 4 c#

这闻到了吗?
我有一些你只能设置一次的属性.它们可以在对象存在期间的任何时间设置,并且无法撤消.
我就是这样实现的.

    private FooThingy _foo;
    public FooThingy Foo
    {
        set { if (null == _foo) _foo = value; }
        get { return _foo; }
    }
Run Code Online (Sandbox Code Playgroud)

但我不喜欢它.我觉得我错过了什么.我有没有?

编辑:为什么我没有在构造函数中.
我不能进入细节,但设置这个结果是<不好的比喻>融化蜡像</坏比喻>.而且我不希望我的构造函数创建已经融化的对象.

pet*_*hen 19

Set-once-properties违反了最小惊喜的原则 - 调用者希望当属性可以设置一次时,可以再次设置它.(当然,除了范围和兼容性检查 - 但它们与特定值或值组合绑定).

在构造函数中初始化它们.
或者,如果他们要编写所有构造函数的许多/复杂,请使用工厂/构建器类:

ThingieBuilder tb = new ThingieBuilder();
tb.FooThingy = 17.23;   // r/w properties
tb.BarThingy = 42;
tb.UseExtendedThingamagicAdapter = true;
Thingie t = tb.Create();
if (t.Bar==42) // r/o property
  ...
Run Code Online (Sandbox Code Playgroud)

或者,将配置对象中的设置分开,可以在构造期间替换或传递.


Fre*_*örk 11

我认为如果将这些值传递给构造函数,并且将其作为只读属性公开,则调用者的设计将更加清晰.如果在构造时无法设置该值,那么在尝试再次设置该值时可能适合抛出异常:

private FooThingy _foo;
public FooThingy Foo
{
    set 
    { 
        if (null == _foo) { _foo = value; }
        else  { throw new WhatEverThatFitsException(); }
    }
    get { return _foo; }
}
Run Code Online (Sandbox Code Playgroud)

只是要非常明确:我不以任何方式促进使用set-once属性 ; 代码示例仅显示我可能使用的方法,如果该值在对象的构造时间因任何原因不可用.那说; 在我参与的任何项目中,我从未遇到过这种情况.

  • `System.Threading.Thread.Name`属性是一次写入属性.不支持这个概念......只是认为框架就是这样一个例子很有趣. (2认同)