Do write-only properties have practical applications?

Viewed 7692

I don't know why I started thinking about this, but now I can't seem to stop.

In C# - and probably a lot of other languages, I remember that Delphi used to let you do this too - it's legal to write this syntax:

class WeirdClass
{
    private void Hello(string name)
    {
        Console.WriteLine("Hello, {0}!", name);
    }

    public string Name
    {
        set { Hello(name); }
    }
}

In other words, the property has a setter but no getter, it's write-only.

I guess I can't think of any reason why this should be illegal, but I've never actually seen it in the wild, and I've seen some pretty brilliant/horrifying code in the wild. It seems like a code smell; it seems like the compiler should be giving me a warning:

CS83417: Property 'Name' appears to be completely useless and stupid. Bad programmer! Consider replacing with a method.

But maybe I just haven't been doing this long enough, or have been working in too narrow a field to see any examples of the effective use of such a construct.

Are there real-life examples of write-only properties that either cannot be replaced by straight method calls or would become less intuitive?

15 Answers

My first reaction to this question was: "What about the java.util.Random#setSeed method?"

I think that write-only properties are useful in several scenarios. For example, when you don't want to expose the internal representation (encapsulation), while allowing to change the state of the object. java.util.Random is a very good example of such design.

Code Analysis (aka FxCop) does give you a diagnostic:

CA1044 : Microsoft.Design : Because property 'WeirdClass.Name' is write-only, either add a property getter with an accessibility that is greater than or equal to its setter or convert this property into a method.

Write-only properties are actually quite useful, and I use them frequently. It's all about encapsulation -- restricting access to an object's components. You often need to provide one or more components to a class that it needs to use internally, but there's no reason to make them accessible to other classes. Doing so just makes your class more confusing ("do I use this getter or this method?"), and more likely that your class can be tampered with or have its real purpose bypassed.

See "Why getter and setter methods are evil" for an interesting discussion of this. I'm not quite as hardcore about it as the writer of the article, but I think it's a good thing to think about. I typically do use setters but rarely use getters.

I have code similar to the following in an XNA project. As you can see, Scale is write-only, it is useful and (reasonably) intuitive and a read property (get) would not make sense for it. Sure it could be replaced with a method, but I like the syntax.

public class MyGraphicalObject
{
    public double ScaleX { get; set; }
    public double ScaleY { get; set; }
    public double ScaleZ { get; set; }

    public double Scale { set { ScaleX = ScaleY = ScaleZ = value; } }

    // more...
}

As far as I'm concerned, they don't. Every time I've used a write-only property as a quick hack I have later come to regret it. Usually I end up with a constructor or a full property.

Of course I'm trying to prove a negative, so maybe there is something I'm missing.

I just came across that situation when writing a program that reads data from a JSON database (Firebase). It uses Newtonsoft's Json.NET to populate the objects. The data are read-only, i.e., once loaded they won't change. Also, the objects are only deserialized and won't be serialized again. There may be better ways, but this solution just looks reasonable for me.

using Newtonsoft.Json;
// ...

public class SomeDatabaseClass
{
    // JSON object contains a date-time field as string
    [JsonProperty("expiration")]
    public string ExpirationString
    {
        set
        {
            // Needs a custom parser to handle special date-time formats
            Expiration = Resources.CustomParseDateTime(value);
        }
    }
    
    // But this is what the program will effectively use.
    // DateTime.MaxValue is just a default value
    [JsonIgnore]
    public DateTime Expiration { get; private set; } = DateTime.MaxValue;
    
    // ...
}

No, I can' imagine any case where they can't be replaced, though there might people who consider them to be more readable.

Hypothetical case:

CommunicationDevice.Response = "Hello, World" 

instead of

CommunicationDevice.SendResponse("Hello, World")

The major job would be to perform IO side-effects or validation.

Interestingly, VB .NET even got it's own keyword for this weird kind of property ;)

Public WriteOnly Property Foo() As Integer
   Set(value As Integer)
     ' ... '
   End Set
End Property

even though many "write-only" properties from outside actually have a private getter.

Well, technically there is nothing wrong with a Setter-only property per-se. The Setter could do some validation, and maybe some other methods - public or private - could depend on it.

For example:

class SomeClass {
    private int _someVar;

    SomeClass(int someVar) {
        if(someVar > 0) _someVar = someVar;
    }

    public int SomeVar {
        set { if(value > 0) _someVar = value; }
    }

     public string SomeFunction(){
       return "This is an important function that uses _someVar " + _someVar;
     }
}

So the declaration itself maybe legal and valid. Your method body is a huge code smell though, but that's not the compilers job to care about.

Related