I have a class like this:
public class Base
{
public Base(string name)
{
this.Name = name;
}
public string Name { get; set; }
public string PrettyName
{
get { return Prettify(Name); }
}
}
and I derive from it:
public class Derived : Base
{
public Derived(Base b) : base(b.Name) { }
}
The Name property should not be accessed; the logical name should be accessed only by PrettyName. So I thought I'd make the property like this:
public string Name { protected get; set; }
But I'm getting this:
Cannot access protected member 'Name' via a qualifier of type 'Base'; the qualifier must be of type 'Derived' (or derived from it)
Why is that? The getter should be exposed to the base class and all its child classes. Am I getting something wrong here?

The getter should be exposed to the base class and all its child classes.
No, not quite. This isn't a matter of automatically implemented properties - it's a matter of what protected means.
Access to a protected member within a subclass has to be through an instance of that subclass (or a further subclass). You can't use Base.Name for an arbitrary Base in Derived.
From section 3.5.3 of the C# spec:
When a
protectedinstance member is accessed outside the program text of the class in which it is declared, and when aprotected internalinstance member is accessed outside the program text of the program in which it is declared, the access must take place within a class declaration that derives from the class in which it is declared. Furthermore, the access is required to take place through an instance of that derived class type or a class type constructed from it. This restriction prevents one derived class from accessingprotectedmembers of other derived classes, even when the members are inherited from the same base class.
A simple solution would be to overload the constructor in Base:
protected Base(Base b) : this(b.Name)
{
}
then in Derived:
public Derived(Base b) : base(b) { }
At that point, you can make the Name setter private, too - or better yet, make it fully read-only:
private readonly string name;
public string Name { get { return name; } }
See more on this question at Stackoverflow