views:

325

answers:

5

Hello. I found a topic on MSDN that talks that yes, this is possible.

I did a test that seems to break this statement:

using System;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            Foo f = new Foo("1");
            Console.WriteLine(f.Bar); // prints 1
            f.Test("2");
            Console.WriteLine(f.Bar);// successfully prints 2
        }
    }

    class Foo
    {
        public Foo(string b)
        {
            this.Bar = b;
        }

        public string Bar { get; private set; }

        public void Test(string b)
        {
            // this would be impossible for readonly field!
            // next error would be occur: CS0191 or CS0191
            // A readonly field cannot be assigned to (except in a constructor or a variable initializer)
            this.Bar = b; 
        }
    }
}

Where am I wrong?

+11  A: 

You're absolutely right. Properly read-only automatically implemented properties are currently impossible. Making the setter private isn't the same thing, regardless of what some books and MSDN might say :)

If I ruled the world, this would not be the case. When I see some of the language designers at NDC 2010 in June (please come along!) I intend to try to persuade, bribe, cajole and generally make a nuisance of myself until they agree. It's just one wafer-thin feature, after all.

Looking at that MSDN article, the text itself doesn't say that it creates a read-only automatic property. It creates an immutable type using an automatic property, and that's correct. The only problematic bits are the comments saying

// Read-only properties.

... which are definitely wrong. The framework agrees with us:

var prop = typeof(Contact).GetProperty("Name");
Console.WriteLine(prop.CanWrite); // Prints True
Jon Skeet
Maybe just ruling a country would do. We could call it Skeetistania.
Mike Two
You don't need to rule the world. Just invent Skeet#
Anthony Pegram
One *wafer-thin* feature translates into many person-weeks of work: http://blogs.msdn.com/ericlippert/archive/2003/10/28/53298.aspx
Brian
@Brian: That's why I'm going to have to persuade, bridge, cajole etc :) But compared with many other features, I believe this really *would* be small.
Jon Skeet
You don't have to convince us that it's a good idea; we know its a good idea. The questions are (1) is this the best possible feature we can do given the time and money budget that we have, and (2) can we spend that budget on solving some more general, more difficult, less "thin" aspect of immutability, of which immutable props are a simple special case? Every narrow "special purpose" feature we add increases the complexity of the grammar; we want to make sure that we're getting good value going forward for that additional complexity.
Eric Lippert
@Eric: Understood on all fronts - and any attempt to solve the wider immutability issue would be very welcome indeed. I should probably point out to others that Eric has patiently listened to this feature request from me in just about every communication medium known to man :) There's one *good* thing about it being painful to add features, mind you: it makes it harder for an imaginative team to add so many features that us mortals can't keep up.
Jon Skeet
+1  A: 

Private set is not the same as "read-only".

Similar to methods or fields, the private keyword makes the visibility of the setter available to only the class itself. Other objects cannot use the setter, but methods of the class itself can call it freely. Hence your test code compiles and works fine.

It appears to external objects as a read-only property, but it isn't read-only in the true definition.

womp
+4  A: 

The property is read-only outside the 'Foo' class. I think that's what article is getting at.

But it's not the same as marking a variable with the 'readonly' keyword.

kervin
+2  A: 

It's confusing. You should differentiate read-only to the c# readonly (what the keyword means).

  • read-only: they mean that no one outside can write to it directly, only read.
  • C# readonly: you can only write to it in the constructor, then never more.
Samuel Carrijo
I would call that 'read-only' and 'read-only in C#'
abatishchev
@abatischchev there's a readonly keyword in c#, which was what I meant
Samuel Carrijo
@persuade: Yes, I'm talking about it too. I mean that something in C# isn't read-only without readonly keyword. It's better ta call it someway else
abatishchev
+1  A: 

No, it's not possible to make an auto-implemented property readonly. For the page you linked:

with auto-implemented properties, both a get and set accessor are required

A read-only property has NO set accessor.

A property without a set accessor is considered read-only

Ben Voigt