代码之家  ›  专栏  ›  技术社区  ›  Nifle Hassan Syed

我应该使用一次性变量吗?

c#
  •  4
  • Nifle Hassan Syed  · 技术社区  · 15 年前

    这有味道吗?
    我有一些属性你只能设置一次。它们可以在对象存在期间的任何时间设置,并且不能撤消。
    然后我像这样执行。

        private FooThingy _foo;
        public FooThingy Foo
        {
            set { if (null == _foo) _foo = value; }
            get { return _foo; }
        }
    

    但我不喜欢。我觉得我错过了什么。是吗?

    编辑 :为什么我在构造函数中没有它。
    我无法详细说明,但将此结果设置为 < 拙劣类比 > 融化蜡像 < 拙劣的类比 > . 我不希望我的构造函数创建已经融化的对象。

    8 回复  |  直到 10 年前
        1
  •  19
  •   peterchen    15 年前

    一旦属性违反最小惊喜原则就设置 -调用方希望当一个属性可以设置一次时,它可以再次设置。(当然,除了范围和兼容性检查之外,它们还绑定到特定的值或值组合)。

    在构造函数中初始化它们。
    或者,如果要编写所有构造函数,请使用factory/builder类:

    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
      ...
    

    或者,分离配置对象中的设置,这些设置可以在构造期间替换或传递。

        2
  •  12
  •   Fredrik Mörk    15 年前

    我认为,如果将这些值传递给构造函数,并将其作为只读属性公开,那么对调用方来说,设计将更加清晰。如果在构建时无法设置该值,则在尝试再次设置该值时,可能需要引发异常:

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

    只是要非常清楚: 我不 以任何方式 促进使用一次性设置属性 ;代码示例只显示 可以 使用, 如果在施工时该值不可用 不管什么原因。也就是说,我从未在我参与过的任何项目中遇到过这种情况。

        3
  •  4
  •   Ian    15 年前

    我建议把它们设置在建筑上,从而使设置者成为私有的。这似乎是更明智的做法。

    如果你想这样做,就抛出某种异常。至少让开发人员知道您没有设置它们的值,而不是默默地忽略它。

        4
  •  1
  •   user110714    15 年前

    我同意弗雷德里克的观点,只读更合理。这样,您只能在构造函数中声明变量(或作为声明的一部分)。我认为做你所做的事情并不能立即清楚地表明这是你想要实现的。

    退房 this MSDN页。

        5
  •  1
  •   F Yaqoob    10 年前

    只需让setters方法而不是属性——期望和行为之间的分离就消失了。该方法可以自由地引发InvalidOperationException,但不期望由属性设置器执行该操作。

    private FooThingy _foo;
    public FooThingy Foo
    {
        get { return _foo; }
    }
    
    public void SetFooThingy(FooThingy value) {
       if (Foo != null) 
          throw new InvalidOperationException("Foo is already set!");
       _foo = value;
    }
    
        6
  •  0
  •   RvdK    15 年前

    如果foothingy是一个像int这样的值对象,它将被0初始化而不是空值。剩下的看起来还可以

        7
  •  0
  •   John Feminella    15 年前

    很难从这个玩具例子中分辨出来,但听起来 _foo 对这个物体的存在相对重要。在这种情况下,它几乎肯定是一个只读属性,在创建时初始化,没有任何公共setter。尽可能地偏爱不变的事物;它使你的生活简单多了!

        8
  •  0
  •   Dan Diplo    15 年前

    制造它们 readonly 并将它们设置在构造函数中。