简体   繁体   English

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

[英]What is the best practice for using .NET Properties?

I am a little confused about how much I SHOULD do with properties. 关于我应该对属性做多少,我有点困惑。 I have heard that properties should always represent a logical property of the class. 我听说属性应该始终代表类的逻辑属性。 Get and Set should almost never throw exceptions with the exception of ArgumentOutOfRange. 除了ArgumentOutOfRange之外,Get和Set几乎不会抛出异常。 Is that true? 真的吗? Is the following example totally wrong? 以下示例是完全错误的吗?

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

Also, If a method in the same class wants to change the value of a property should it go through the set accessor of the property or just modify the private variable _Registered directly? 此外,如果同一类中的方法想要更改属性的值,它应该通过属性的set访问器还是直接修改私有变量_Registered?

If you have any additional advice when using properties please include! 如果您在使用酒店时有任何其他建议请包含! Thanks 谢谢

Here is a link to the Design Guidelines for properties from the MSDN. 以下是MSDN中属性设计指南的链接。 Make special note of the Property vs Method section. 请特别注意“ 属性与方法”部分。

From my own personal experience, you shouldn't use properties to do a lot of work. 根据我个人的经验,你不应该使用属性来做很多工作。 They should be returning information that has already been retrieved. 他们应该返回已经检索过的信息。 I'm currently working on a code base which has a lot of lazy loaded properties that retrieve information from a web service. 我目前正在开发一个代码库,它有很多延迟加载的属性,可以从Web服务中检索信息。 Looking at the properties of a class while debugging causes all of the properties to be evaluated, causing functional evaluation to time out and the ASP.NET process to crash. 在调试时查看类的属性会导致评估所有属性,从而导致功能评估超时并使ASP.NET进程崩溃。

In this case I think it is more logical to use methods because you are performing an action. 在这种情况下,我认为使用方法更合乎逻辑,因为您正在执行操作。

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

A narrow answer: I like using read-only properties when I've got a value that takes a bit of work to get , but that I want the "rest of the world" (even callers inside the same class) to think of as a variable whose value is just always available. 一条狭窄的回答:我喜欢使用只读属性时,我已经有了一个值,需要多一点的工作来获取 ,但我想要的(同一类中甚至用户)“世界其他地方”想为一个变量,其值始终可用。 The property will do the work to get the value and then simply return (perhaps with optimizations like caching/etc). 该属性将完成工作以获取值 ,然后简单地返回(可能使用缓存等等优化)。

The alternative would be a "get" method, and that's fine... but I like using a property when I don't want the caller burdened with the idea that there's work involved in fetching/figuring the value. 替代方案是一个“获取”方法,这很好......但是当我不希望调用者负担获取/计算值的工作时,我喜欢使用属性。

In this case, since you call another method when the property is changed, if you want to keep that functionality then set it using the Accessor . 在这种情况下,由于在更改属性时调用另一个方法,因此如果要保留该功能,请使用Accessor进行设置。 If it's just storing a value, you are ever so slightly better off using the _Registered variable directly. 如果只是存储一个值,那么直接使用_Registered变量就会好一些。

I will grant you that often it makes sense to have a property do more than just hold a value, but in my opinion, your example is horrible. 我会告诉你,让财产做的不仅仅是持有一个价值是有意义的,但在我看来,你的榜样太可怕了。 I would have a method that registers/unregisters the device and a simple getter for the current state. 我将具有寄存器/注销装置和简单的吸气剂的当前状态的方法 My general rule is that if I'm performing an action, I use a method, but if I'm merely changing a value, then a property is more appropriate. 我的一般规则是,如果我正在执行一个动作,我使用一个方法,但如果我只是改变一个值,那么一个属性更合适。 Now, how the property handles that may involve doing some computation or I/O, but the important thing is the expectation of the class consumer. 现在,属性如何处理可能涉及进行一些计算或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; }

Also, I tend to force even the class code to go through the property -- this isolates any changes that I might make in how the property operates to the property code itself. 此外,我倾向于强制甚至类代码通过属性 - 这隔离了我可能在属性如何操作属性代码本身的任何更改。 Other parts of the same class need not know how the property works. 同一类的其他部分不需要知道该属性如何工作。 There will be exceptions obviously -- like when you want or need to avoid some computation that the property performs, but still need the value to be updated -- but that's my general rule. 显然会有例外 - 比如当你想要或者需要避免某些属性执行的计算时,但仍然需要更新值 - 但这是我的一般规则。

To address the issue of the using the field directly or the property accessor/mutator, I am in favour of the property. 为了解决直接使用字段或属性访问者/ mutator的问题,我赞成该属性。 If you should have a default value beeing returned in the accessor or raise property change events (or the like) in the mutator you will bypass this functionality by accessing the field directly. 如果您应该在访问器中返回默认值,或者在mutator中提升属性更改事件(或类似内容),则可以通过直接访问该字段来绕过此功能。 If an extending class overrides the property, you may inadvertantly bypass the extending class if you access the field directly. 如果扩展类覆盖该属性,则如果直接访问该字段,则可能无意中绕过扩展类。

There are cases where field access (private) is the way to go, but I always favour the property, unless there is a good reason to access the field. 有些情况下,现场访问(私人)是要走的路,但我总是喜欢这个属性,除非有充分的理由去访问该领域。

Here are some rules that I've realized over time. 以下是我随着时间的推移已经实现的一些规则。 Most are my opinions but I like to think they are good ideas. 大多数是我的意见,但我喜欢认为他们是好主意。 :) Edit: I just realized that most of these are covered in the Property Usage guidelines. :) 编辑:我刚刚意识到其中大部分都包含在“ 财产使用”指南中。

Getters 吸气剂

  • You should prefer that getters not alter state. 你应该更喜欢吸气剂不改变状态。 If you have a getter that does alter program state, mark it with [DebuggerBrowsable(DebuggerBrowsableState.Never)] . 如果你有一个确实改变程序状态的getter,用[DebuggerBrowsable(DebuggerBrowsableState.Never)]标记它。
  • Prefer that getters can be called from any thread. 首选可以从任何线程调用getter。
  • Prefer that getters be trivially computed, since they are used in such a way that leads people to believe they won't incur a performance penalty. 喜欢简单地计算吸气剂,因为它们的使用方式使人们相信它们不会产生性能损失。 If they could take some time to execute, mark them with either the DebuggerBrowsable attribute like above or with [DebuggerDisplay("Some display text")] (where the text is trivially computed). 如果它们可能需要一些时间来执行,请使用上面的DebuggerBrowsable属性或使用[DebuggerDisplay("Some display text")]标记它们(其中文本是通过简单计算的)。 Forgetting the latter can have a detrimental impact on debugger performance. 忘记后者会对调试器性能产生不利影响。
  • Getters can throw at least the following exceptions: Getters至少可以抛出以下异常:
    • InvalidOperationException
    • ObjectDisposedException

Setters 塞特斯

  • Prefer that whenever you set two properties back-to-back, it doesn't matter which comes first. 首选 ,无论何时背靠背设置两个属性,首先出现哪个属性并不重要。
  • If the setter has a precondition that cannot be tested through publicly exposed properties, it should be marked protected or private. 如果setter具有无法通过公开公开属性进行测试的前提条件,则应将其标记为受保护或私有。
  • It's ok to restrict calling setters to a particular thread, but if you do so it needs to be documented and your object should either implement ISynchronizeInvoke or expose a Dispatcher property. 可以将调用setter限制为特定线程,但如果这样做,则需要记录,并且您的对象应该实现ISynchronizeInvoke或公开Dispatcher属性。
  • Setters can throw at least the following exceptions: Setter至少可以抛出以下异常:
    • An ArgumentException ( ArgumentNullException , ArgumentOutOfRangeException , etc. as appropriate) ArgumentExceptionArgumentNullExceptionArgumentOutOfRangeException等,视情况而定)
    • InvalidOperationException
    • ObjectDisposedException

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 并非总是填充的类属性。 什么是最佳做法? - Class properties that aren't always populated. What is best practice? 从继承的类更改基础对象属性的最佳实践是什么? - what is the best practice of changing base object properties from inherited class 使用公共字段的最佳做法是什么? - What is the best practice for using public fields? 分发.NET 3.5和4.0应用程序使用的组件的最佳实践是什么? - What is the best practice for distributing a component that is used by .NET 3.5 and 4.0 applications? 在.NET中存储数据库连接详细信息的最佳实践是什么? - What is the best practice for storing database connection details in .NET? 在.Net库中命名集合的最佳实践是什么? - What is the best practice for naming collections within a library in .Net? .net - 保护WPF应用程序配置设置的最佳做法是什么? - .net - What is the best practice for securing WPF application configuration settings? ADO.NET - 获取datareader值的最佳做法是什么? - ADO.NET - What is best practice for getting datareader values? ASP.NET MVC中异步编程的最佳实践是什么? - What is the best practice for asynchronous programming in ASP.NET MVC? 在.NET中对私有方法进行单元测试的最佳实践是什么? - What is the best practice for unit testing private methods in .NET?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM