简体   繁体   English

如果该字段仅用于内部逻辑,是否需要属性?

[英]Is a Property necessary if the field is used only for internal logic?

I know how properties are used to expose fields, what are the benefits and so on. 我知道如何使用属性公开字段,有什么好处等等。 What I am trying to understand (and I've searched quite a bit) is: 我想要了解的(并且已经搜索了很多)是:

Does every single field need to always have a wrapping property, even if it does NOT need to be exposed and is used only in internal logic? 即使每个字段都不需要公开并且仅在内部逻辑中使用,它是否也需要始终具有包装属性?

I would assume that the answer is yes, because even if its modified in some internal logic, the new value would still need to be validated. 我认为答案是肯定的,因为即使在某些内部逻辑中对其进行了修改,新值仍需要进行验证。

If the answer is yes, is this why its so common for a property to have public get and private set? 如果答案是肯定的,这是否就是为什么拥有公共场所和私人场所的财产如此普遍?

Edit: Thank you for all the answers that you gave me, but most of them have nothing to do with my question, most of you are talking about big and complex classes, my simple question is, should I have a wrapping property for a field thats used only inside its class and does not need to be exposed. 编辑:谢谢你给我的所有答案,但其中大多数与我的问题无关,你们中的大多数都在谈论大型和复杂的类,我的简单问题是,我是否应该为字段设置包装属性多数民众赞成在仅在其类内使用,不需要暴露。

Edit 2: Some of the answers suggest something that can be accepted as a no answer, suggesting that a property should not be used if there is no need for logic 编辑2:有些答案表明可以接受,但没有答案,这表明如果不需要逻辑,则不应使用属性

Edit 3: Thank you all, I reread most of the comments and it started making sense, just like always :) 编辑3:谢谢大家,我重新阅读了大部分评论,并且像往常一样:)开始有意义:)

This isn't one of those issues where you can do a whole lot of damage getting it wrong. 这不是您可以对其造成很大损害的许多问题之一。

That said, no, don't make it a property unless you need to put some logic in the setter or getter, and you probably don't need to. 就是说, 不,除非您需要在setter或getter中添加一些逻辑,并且您可能不需要,否则不要将其设为属性。 Don't add code that doesn't serve some purpose. 不要添加没有用处的代码。

"Fields are bad" isn't a purpose. “字段不好”不是目的。 And in fact, it's nonsense. 实际上,这是胡说八道。 Fields exist for a reason. 存在字段是有原因的。

If the class is so huge that nobody can keep track of it all and you need to hide parts from each other, it's too big and it's doing too much. 如果班级太多了,没人能跟踪所有内容,而您又需要彼此隐藏部分,那么它太大了,而且做得太多。 Refactor it into two or more classes that are manageable. 将其重构为两个或更多可管理的类。

Very often, as a large class grows (most often something that doesn't naturally have a very tight focus, like a major viewmodel, or Window or a Form in the bad old days), we find ourselves writing little "subsystems" within the class that have a field or two with logic in the set and/or get blocks. 很多时候,随着大类的增长(大多数时候,自然而然地没有很紧的焦点,例如在糟糕的过去,主要的视图模型,Window或Form),我们发现自己在内部编写了一些“子系统”类,在set和/或get块中具有一个或两个带有逻辑的字段。 That's a candidate for refactoring into a separate small class with a clean interface, an easily reusable ball of logic and state that doesn't have its internals mixed in with your big class's internals. 那是一个候选者,可以将其重构为具有干净接口的独立小类,易于重用的逻辑球和状态球,而其内部结构不会与大类的内部结构混合在一起。 Give the big class a private copy of the little helper class. 给大班级提供小帮手班级的私人副本。 Drag and drop code is an example that springs to mind. 拖放代码是一个让人想到的示例。

It's a classic progression: 这是一个经典的进步:

  1. I'll just add a flag 我只加一个标志
  2. That flag I added yesterday has to be an enum 我昨天添加的标记必须是枚举
  3. With a flag 带有标志
  4. Wait, I just copy and pasted a block of code. 等等,我只是复制并粘贴了一段代码。 Put that in a setter on the flag. 把它放在旗子上的塞特犬上。
  5. And a hel... two helper methods. 还有一个...两个辅助方法。
  6. Let's put a #region around that mess so I don't have to look at it. 让我们在那个混乱的地方放置一个#region ,这样我就不#region它了。
  7. We're going to have to copy and paste that whole mess into another class. 我们将不得不将整个混乱复制并粘贴到另一个类中。 Good thing it's all in one place! 好东西全都在一个地方!
  8. It wasn't all in one place. 并非一处都在。
  9. What's my manager doing with that jacket with the funny sleeves? 我的经理对那件带有有趣袖子的外套怎么办?

If you ever reach Stage 7, it's past time for an intervention. 如果您达到了第7阶段的要求,那就已经是干预的时候了。

Private properties are just the first tiny whiff of what may turn into a noxious code smell over time. 随着时间的流逝,私有财产只是可能会变成有害的代码气味的第一小口气。 They're not evil, but they may be a sign that your code is showing a tendency to grow on the wrong axis. 它们不是邪恶的,但是它们可能表明您的代码显示出在错误的轴上增长的趋势。

Update 更新

On internal vs external validation 内部与外部验证

Very often, a class needs to be able to break its own rules, and do so cleanly and straightforwardly. 通常,一个类需要能够打破自己的规则,并且干净利落地做到这一点。 For example, validation of one property/field often depends on values of others (date ranges, etc.). 例如,对一个属性/字段的验证通常取决于其他属性/字段的值(日期范围等)。 Your classe's internals should be able to set them all in arbitrary order without any funny business (sometimes you see "_disableValidation" flags to work around this issue -- a code smell). 您的班级内部人员应该能够以任意顺序设置所有内容,而无需做任何有趣的事情(有时您会看到“ _disableValidation”标志来解决此问题-代码有气味)。 Inside the class, validation should be voluntary, and the class should be kept simple enough so that isn't a problem. 在班级内部,验证应该是自愿的,并且班级应保持足够简单,这样就不会有问题。 A class needs to permit itself to put itself in an invalid state temporarily, while forbidding or controlling the ways in which any external code can put it in an invalid state. 一个类需要允许自己暂时将自己置于无效状态,同时禁止或控制任何外部代码将其置于无效状态的方式。 Maybe if external code puts it in an invalid state, that's permitted by code, but it drives UI that hassles the user. 也许,如果外部代码将其置于无效状态,这是代码所允许的,但它会导致困扰用户的UI。 You don't want to have weird flags to allow your constructor to do its job without popping up a message box or something. 您不希望使用怪异的标志来允许您的构造函数在不弹出消息框之类的情况下完成其工作。

Sometimes a class needs to run around nekkid in the privacy of its own home. 有时,一个班级需要在自己家里的私密环境中四处走动。 Validation should be on inputs from code external to the class. 验证应基于类外部代码的输入。

There's no need to do it but by using a property instead of a field you're more flexible because you can preprocess getting and setting a variable. 不需要这样做,但是通过使用属性而不是字段,您可以更加灵活,因为您可以预处理获取和设置变量。 Changing a field to a property while it's already in use in other code can be a breaking change. 在其他代码中已经使用某个字段时将其更改为属性可能是一项重大更改。 So if you don't know what to choose, go with a property to be on the safe and most flexible side. 因此,如果您不知道要选择什么,请选择一个安全可靠且最灵活的物业。

YAGNI YAGNI

if you don't use property - do not create it. 如果您不使用属性-不要创建它。
If you need change field some how or change logic how it created/updated you will be able to do it without property. 如果您需要一些更改字段或更改逻辑创建/更新方式的信息,则无需属性即可。

Because you do not expose it - you don't need to worry about breaking some other code. 因为您没有公开它-无需担心会破坏其他代码。

if you have some "complex" logic which instantiate/update that field - create a private methods for it. 如果您有一些实例化/更新该字段的“复杂”逻辑-请为其创建私有方法。

Putting some "extra" logic in the setter or even worth add some "side-effect" on the getter - can lead in some odd behavior or bugs, because when I initialize class 在setter中添加一些“额外”逻辑,甚至值得在getter上添加一些“副作用”-可能会导致某些奇怪的行为或错误,因为当我初始化类时

var order = new Order
{
    Id = 1001,
    Reference = "Reference one",
    CustomerId = 2001        
}

I do not expect that assigning CustomerId will cause in some database queries or execution of some complex logic. 我不希望分配CustomerId会导致某些数据库查询或某些复杂逻辑的执行。 Instead 代替

var order = new Order
{
    Id = 1001,
    Reference = "Reference one"      
};
order.SetCustomer(customerid);

暂无
暂无

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

相关问题 使用用作受保护字段的内部类型 - Using an internal type used as protected field 模板只能用于字段访问、属性访问、单维数组索引错误 - Templates can be used only with field access, property access, single-dimension array index error 格式化DateTime错误“模板只能用于字段访问,属性访问,单维数组索引..” - formatting DateTime error “Templates can be used only with field access, property access, single-dimension array index..” InvalidOperationException:模板只能与字段访问、属性访问、单维数组索引自定义索引器表达式一起使用 - InvalidOperationException: Templates can be used only with field access, property access, single-dimension array index custom indexer expressions “模板只能用于字段访问、属性访问、单维数组索引或单参数自定义索引器表达式”错误 - “Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions” error 模板只能与字段访问,属性访问,一维数组索引或单参数自定义索引器表达式一起使用 - Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions unity WaitFortimeSeconds 内部逻辑 - Unity WaitFortimeSeconds internal logic 具有受保护的二传手的可空属性,推断为Friend(Internal)字段 - Nullable Property with protected setter, inferred as Friend(Internal) Field 模板只能用于现场访问 - Templates can be used only for field access 这是什么类型的财产? 有必要吗? - What kind of property is this? is it necessary?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM