简体   繁体   English

具有空访问者的属性

[英]Properties with empty accessors

Though I'm of course familiar with auto-properties, I just ran across this at work, which seems to be a distinctly different beast: 虽然我当然熟悉自动属性,但我在工作中遇到过这个问题,这似乎是一个截然不同的野兽:

public SomeType SomeProp
{
  get
  {
    return someField;
  }
  set
  {
  }
}

I was surprised it even compiled, and I imagine it must be a bug: the property seems to allow setting, but doing so does absolutely nothing. 我很惊讶它甚至编译,我想它一定是一个bug:该属性似乎允许设置,但这样做绝对没有。

Is there a use for this construct? 这个结构有用吗? Is it like those "Close Door" buttons in elevators that don't do anything, but make the user feel good? 电梯中的那些“关门”按钮是不是做了什么,但让用户感觉良好?

Why would you expect it not to compile? 为什么你不期望它不编译? The setter is just a void method with a single parameter, effectively. 有效地,setter只是一个带有单个参数的void方法。 You can write broken methods perfectly easily without expecting the compiler to notice - and the same is true of properties. 您可以非常轻松地编写损坏的方法,而无需编译器注意 - 属性也是如此。

I can't easily imagine any case where this would be deliberate, however, other than for "partial" implementations - eg to demonstrate language features, or if you're testing something that does set a property, but you don't care what the test sets it to. 我不能很容易想象这个地方会是故意的,但是其他比“偏”实现任何情况下-例如演示语言特性,或者如果你要测试的东西, 设置属性,但你不关心什么测试设置为。 (I'd personally still usually at least record that the property had been set.) (我个人通常至少会记录该物业已被设定。)

You often see this when a result needs to be serialized in a web service or using an XML or binary serializer. 当结果需要在Web服务中序列化或使用XML或二进制序列化程序时,您经常会看到这种情况。

It's lazy and sloppy, but it happens often. 这是懒惰和草率,但它经常发生。 This leaves the object with the "appearance" that the property is settable. 这使对象具有属性可设置的“外观”。 If it's done to implement an interface and allow compilation, then the developer who did it needs to be beaten liberally about the head and shoulders with a blunt object, as he just broke the interface. 如果它是为了实现一个接口并允许编译,那么做它的开发人员需要被一个钝器对头部和肩膀大肆殴打,因为他刚刚打破了界面。 If there is a valid reason that it can't be implemented, then the developer needs to kick it back up to the architect for review. 如果存在无法实现的正当理由,则开发人员需要将其重新提交给架构师进行审核。 You don't just leave empty stubbed methods behind when implementing an interface. 实现接口时,不要只留下空的存根方法。 If you don't have a technique defined for implementation at the moment, then at least throw a new NotImplementedException so the unit tests will catch it. 如果您目前没有为实现定义的技术,那么至少抛出一个新的NotImplementedException,以便单元测试能够捕获它。

As far as serialization: ReadOnly properties don't get included in regular serialization, and that can leave the property unavailable to a web service client. 就序列化而言:ReadOnly属性不会包含在常规序列化中,并且可能使该属性对Web服务客户端不可用。 (ref: Read-Only Properties Cannot Be Exposed by XML Web Services .) This is one of the reasons we should all be moving to WCF and DataContracts. (参考: XML Web服务不能公开只读属性 。)这是我们应该转向WCF和DataContracts的原因之一。 If you accept this class as an input type for a method through WCF, then again retrieve the blunt object. 如果您通过WCF接受此类作为方法的输入类型,则再次检索钝对象。

This doesn't seem useful by itself but consider an interface that required classes to have a SomeProp and you need to implement this interface in your class but have SomeProp only readable and not writeable. 这本身似乎并不有用,但考虑一个需要类具有SomeProp的接口,您需要在类中实现此接口,但SomeProp只能读取且不可写。

public interface IQuestion
{
    public int AnwserToLife { get; set; } //leave out 'set' for read-only
}

public class HitchHiker : IQuestion
{
    public int AnwserToLife
    {
        get
        {
            return 42;
        }
        set
        {  
            //never changes
        }
    }
}

There are a few use cases, where this would be a necessary workaround, some of which I have already encountered "in the wild". 有一些用例,这将是一个必要的解决方法,其中一些我已经“在野外”遇到过。

Eg: The property is a remains from old times, no longer of use, but some other part of the app has never been updated (Source lost? Third party?) and insists on setting the property. 例如:该属性是旧时的遗骸,不再使用,但应用程序的其他部分从未更新过(源丢失?第三方?)并坚持设置该属性。 I have seen that in old code, that required plugins to set a isDirty property after updating some dataset, when the implementation changed to observe the dataset on itself, the isDirty property became useless, but couldn't be put away, because other code still wants to set it. 我已经看到,在旧代码中,需要插件在更新某些数据集后设置isDirty属性,当实现更改为观察自身的数据集时,isDirty属性变得无用,但无法放弃,因为其他代码仍然想要设置它。

I would recommend avoiding this kind of programming. 我建议避免这种编程。 It compiles, because there is no reason it shouldn't, but if the interface requires you to implement a setter method, then there are two options: 它编译,因为它没有理由不应该,但如果接口要求你实现一个setter方法,那么有两个选项:

  1. Either the setter is redundant and the property should be made read-only, or 设置器是冗余的,属性应该是只读的,或者
  2. There exists a part of your code which will set this value and falsely assume that it worked. 您的代码中存在一部分将设置此值并错误地假设它有效。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM