简体   繁体   中英

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.

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. 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.

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.

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. (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. If you accept this class as an input type for a method through WCF, then again retrieve the blunt object.

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.

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.

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:

  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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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