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

问题描述 投票:5回答:7

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

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

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

如果您在使用酒店时有任何其他建议请包含! 谢谢

.net properties exception
7个回答
6
投票

以下是MSDN中属性设计指南的链接。 请特别注意“ 属性与方法”部分。

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


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;
    }
}

1
投票

一条狭窄的回答:我喜欢使用只读属性时,我已经有了一个值,需要多一点的工作来获取 ,但我想要的(同一类中甚至用户)“世界其他地方”想为一个变量,其值始终可用。 该属性将完成工作以获取值 ,然后简单地返回(可能使用缓存等等优化)。

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


0
投票

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


0
投票

我会告诉你,让财产做的不仅仅是持有一个价值是有意义的,但在我看来,你的榜样太可怕了。 我将具有寄存器/注销装置和简单的吸气剂的当前状态的方法 。 我的一般规则是,如果我正在执行一个动作,我使用一个方法,但如果我只是改变一个值,那么一个属性更合适。 现在,属性如何处理可能涉及进行一些计算或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; }

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


0
投票

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

有些情况下,现场访问(私人)是要走的路,但我总是喜欢这个属性,除非有充分的理由去访问该领域。


0
投票

以下是我随着时间的推移已经实现的一些规则。 大多数是我的意见,但我喜欢认为他们是好主意。 :) 编辑:我刚刚意识到其中大部分都包含在“ 财产使用”指南中。

吸气剂

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

塞特斯

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