views:

294

answers:

7

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 seem 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 in order 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?

+6  A: 

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.

Kaleb Brasee
Are you maybe referring to property injection as a means of DI? And if so, what's the advantage over constructor injection?
Aaronaught
Yeah, I usually use property injection with setters instead of constructor injection. I actually prefer the idea of constructor injection, but I use the Spring framework, and using setters instead of constructors makes the XML file clearer.
Kaleb Brasee
Ah, okay. I haven't used Spring much - looking at how it works, that does make a lot of sense. +1 for that!
Aaronaught
@Kaleb - Would be nice to see a practical example...
Robert Lamb
But why is a write-only property better than a Set method? (E.g. SetName(string name) .) I would say that it's not better. One usually expects properties to be readable. Making one write-only would violate the Principle of Least Surprise. A Set method doesn't have this problem.
dangph
A: 

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.

Michael Stum
+2  A: 

My first reaction to this question was: "What about a 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.

dfa
A: 

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.

Dario
Any property can be replaced with methods. In fact, properties in many languages are nothing more than a pair of methods (getter and setter). .NET adds a little bit of metadata saying "these two methods go together" to make reflection call it a "property", but other than reflection properties are just syntactic sugar.
Ben Voigt
+4  A: 

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.

Dan
Nice - at least that tells me I'm not crazy for asking the question.
Aaronaught
A: 

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.

Jonathan Allen
A: 

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...
      }
Robert Lamb