使用.NET属性的最佳做法是什么?

时间:2010-02-25 15:04:30

标签: .net properties exception

我对我应该对房产做多少感到困惑。 我听说属性应该始终代表类的逻辑属性。 除了ArgumentOutOfRange之外,Get和Set几乎不会抛出异常。真的吗?以下示例是完全错误的吗?

public bool DeviceRegistered
{
    get{ return _Registered;}
    set
    {
        if(value)
        {
            RegisterDevice();
            _Registered = true;
        }
        else
        {
            UnRegisterDevice();
            _Registered = false;
        }
    }
}

此外,如果同一类中的某个方法想要更改属性的值,它是应该通过属性的set访问器还是直接修改私有变量_Registered?

如果您在使用酒店时有任何其他建议,请加入! 感谢

7 个答案:

答案 0 :(得分:6)

以下是MSDN中Design Guidelines for properties的链接。请特别注意Property vs Method部分。

根据我个人的经验,你不应该使用属性来做很多工作。他们应该返回已经检索过的信息。我目前正在开发一个代码库,它有很多延迟加载的属性,可以从Web服务中检索信息。在调试时查看类的属性会导致评估所有属性,从而导致功能评估超时并使ASP.NET进程崩溃。

答案 1 :(得分:4)

在这种情况下,我认为使用方法更合乎逻辑,因为您正在执行操作。

private volatile bool _DeviceRegistered;
private readonly object _Lock = new object();

public bool DeviceRegistered
{
    get { return _DeviceRegistered; }
}

public void RegisterDevice()
{
    lock (_Lock) // A good idea to lock
    {
        // ........
        _DeviceRegistered = true;
    }
}

public void UnregisterDevice()
{
    lock (_Lock)
    {
        // ........
        _DeviceRegistered = false;
    }
}

答案 2 :(得分:1)

一个狭隘的答案:我喜欢使用只读属性,当我有一个值需要做一些工作来获取,但我想要“世界其他地方”(甚至同一类中的调用者)将其视为一个始终可用的值的变量。该属性将完成获取值的工作,然后返回(可能还有缓存/等优化)。

另一种方法是“获取”方法,这很好......但是当我不希望调用者负担获取/计算值的工作时,我喜欢使用属性。

答案 3 :(得分:0)

在这种情况下,由于您在更改属性时调用另一个方法,因此如果要保留该功能,请使用Accessor进行设置。如果它只是存储一个值,那么直接使用_Registered变量会稍微好一些。

答案 4 :(得分:0)

我会告诉你,让一个财产做的不仅仅是持有一个价值是有意义的,但在我看来,你的榜样是可怕的。我有一个方法注册/取消注册设备和一个简单的当前状态的getter。我的一般规则是,如果我正在执行一个动作,我使用一个方法,但如果我只是改变一个值,那么一个属性更合适。现在,属性如何处理可能涉及进行一些计算或I / O,但重要的是对类消费者的期望。

public void Register()
{
  ...do some stuff...
  this.Registered = true;
}

public void Unregister()
{
  ...do some stuff...
  this.Registered = false;
}

public bool Registered { get; private set; }

此外,我倾向于强制甚至类代码通过属性 - 这隔离了我可能在属性如何操作属性代码本身的任何更改。同一类的其他部分不需要知道该属性如何工作。显然会有例外 - 比如当你想要或者需要避免属性执行的某些计算时,但仍然需要更新值 - 但这是我的一般规则。

答案 5 :(得分:0)

为了解决直接使用字段或属性访问者/ mutator的问题,我赞成该属性。如果您应该在访问器中返回默认值,或者在mutator中提升属性更改事件(或类似内容),则可以通过直接访问该字段来绕过此功能。如果扩展类覆盖该属性,则如果直接访问该字段,则可能无意中绕过扩展类。

有些情况下,现场访问(私有)是可行的方法,但我总是喜欢这个属性,除非有充分的理由去访问该字段。

答案 6 :(得分:0)

以下是我随着时间的推移实现的一些规则。大多数是我的意见,但我喜欢认为他们是好主意。 :) 修改:我刚刚意识到Property Usage指南中涵盖了大部分内容。

吸气剂

  • 你应该更喜欢吸气剂不会改变状态。如果你有一个 改变程序状态的getter,请用[DebuggerBrowsable(DebuggerBrowsableState.Never)]标记它。
  • 首选可以从任何线程调用getter。
  • 首选可以简单地计算吸气剂,因为它们的使用方式会导致人们相信它们不会产生性能损失。如果它们可能需要一些时间来执行,请使用上面的DebuggerBrowsable属性或使用[DebuggerDisplay("Some display text")](其中文本是通过简单计算的)来标记它们。忘记后者会对调试器性能产生不利影响。
  • Getters至少可以抛出以下异常:
    • InvalidOperationException
    • ObjectDisposedException

塞特斯

  • 首选,无论何时背靠背设置两个属性,哪个首先出现都无关紧要。
  • 如果设定者的前提条件无法通过公开公开的属性进行测试,则应将其标记为受保护或私有。
  • 可以将调用setter限制为特定的线程,但如果这样做,则需要记录,并且您的对象应该实现ISynchronizeInvoke或公开Dispatcher属性。
  • Setters至少可以抛出以下异常:
    • ArgumentExceptionArgumentNullExceptionArgumentOutOfRangeException等,视情况而定)
    • InvalidOperationException
    • ObjectDisposedException