Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Sometimes I would like to declare a property like this:

public string Name { get; readonly set; }

I am wondering if anyone sees a reason why such a syntax shouldn't exist. I believe that because it is a subset of "get; private set;", it could only make code more robust.

My feeling is that such setters would be extremely DI friendly, but of course I'm more interested in hearing your opinions than my own, so what do you think?

I am aware of 'public readonly' fields, but those are not interface friendly so I don't even consider them. That said, I don't mind if you bring them up into the discussion

Edit

I realize reading the comments that perhaps my idea is a little confusing. The ultimate purpose of this new syntax would be to have an automatic property syntax that specifies that the backing private field should be readonly. Basically declaring a property using my hypothetical syntax

public string Name { get; readonly set; }

would be interpreted by C# as:

private readonly string name;
public string Name
{
    get
    {
        return this.name;
    }
}

And the reason I say this would be DI friendly is because when we rely heavily on constructor injection, I believe it is good practice to declare our constructor injected fields as readonly.

share|improve this question
1  
Because properties is just syntactic sugar over get/set methods. And it would be nice if you expanded more on what you mean by "ID friendly" –  Euphoric Oct 12 '12 at 12:48
1  
I think he means Dependency Injection friendly. –  Wyatt Barnett Oct 12 '12 at 13:09
    
I have no clue what you think it would do differently. Are you suggesting it would be settable by a DI container but not by anything else? –  pdr Oct 12 '12 at 13:44
    
Wyatt is right. @pdr nothing would go different, but it would allow me to use automatic property syntax while keeping my constructor injected fields readonly. Right now, if i want to use the automatic property syntax, I can specify that the backing field should be private ("private set;") but not readonly. –  Luis Ferrao Oct 12 '12 at 14:21
    
@LuisFerrao: Your update helped me clarify my own issues with the question. I was taking issue with the wrong thing. I have answered it now. –  pdr Oct 12 '12 at 14:32

2 Answers 2

As mentioned in the comments, properties are just syntactic sugar. When they are turned into methods, "readonly" would no longer be syntactically correct.

You can expose a private variable through a read-only property for the desired effect:

private readonly string _name;

public string Name {
    get {
        return _name;
    }
}

public MyObject(string injectedName) {
    _name = injectedName;
}

Edit:

How do you envision your idea would work (if it was possible)? Your readonly property wouldn't work in an initialization list because the constructor is already finished executing at that point.

share|improve this answer
    
How is that significantly different from { get; private set; }? –  pdr Oct 12 '12 at 13:42
1  
@pdr With private set, you can set the property outside of the constructor / field initialization. With readonly field, you can't do that, which means it actually ensures immutability of that property. But I'm assuming you already knew that, so I guess I don't understand your question. –  svick Oct 12 '12 at 13:58
1  
@pdr The external interface of the class is the same, but while doing maintenance on the class a readonly field communicates that it may only be changed once (in the constructor), and a private setter means that you can change it from anywhere inside the class. –  dvdvorle Oct 12 '12 at 14:00
    
Simon, I updated my question, let me know if it makes more sense. –  Luis Ferrao Oct 12 '12 at 14:14

I think your problem is that you're automatically assuming a getter for each injected property.

Auto-properties with private setters are for types where you have

public class Person
{
    public string Name { get; private set; }
    public int Age { get; private set; }

    public Person (string name, int age)
    {
        Name = name;
        Age = age;
    }
}

and very little logic. This means it doesn't matter if you can, technically speaking, set your auto-properties outside of the constructor. You probably won't. And, as far as an external class goes, you're still immutable.

But you don't use DI to generate objects like this one.

You use DI to inject services that you apply logic to, like this:

public Foo : IFoo
{
    private IBar _bar;
    private IGrommit _grommit;

    public Foo(IBar bar, IGrommit grommit)
    {
        _bar = bar;
        _grommit = grommit;
    }

    public string GrommitMyBarForAName()
    {
        return _grommit.DoStuff(bar).Name;
    }
}

In these cases, you should not automatically add an accessor for _bar, just because you can. You don't want to give public access to it, not even readonly.

There will be cases when you feel you have to but, in those cases, you should first reconsider your design. It's probably wrong.

If you're absolutely positive that you should, then add a standard accessor, but this should not be a common enough situation that you feel a need to complain that there should be a syntax to allow you to have an auto-property for it.

share|improve this answer
    
@LuisFerrao: They can. They often aren't. And, where they are, they should still be private. See the "tell, don't ask" principle: pragprog.com/articles/tell-dont-ask –  pdr Oct 12 '12 at 15:33
    
After carefully reading your reply, I realizing where you are getting at. In my example, I use Name because I'm talking about C# syntax in general, but the property in my example can be of an abstract type. You seem to imply that public getters defeat the purpose of DI, which is confusing me. Using your exact example, imagine IFoo is itself a member of IParentFoo, from IGrandpa I might just want to foreach (var parentFoo in _parentFooList) parentFoo.IFoo.GrommitMyBarForAName(), in which case an IFoo public getter comes in handy... –  Luis Ferrao Oct 12 '12 at 15:42
    
...without getters, IParentFoo would need itself a wrapper method that would call _iFoo.GrommitMyBarForAName() just so that IGrandpa can call _parentFoo.WrapperMethodForGrommitMyBarForAName(). This wrapper method would just be duplication of code and it might not even make sense for IParentFoo. –  Luis Ferrao Oct 12 '12 at 15:45
1  
I'm +1ing you anyway for your GrommitMyBarForAName() method name :) (or I would if I had the reputation) –  Luis Ferrao Oct 12 '12 at 15:48
    
@LuisFerrao: If it doesn't make sense for IParentFoo then it shouldn't be part of it. Let IGrandpa have the reference to _foo. –  pdr Oct 12 '12 at 15:48

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.