tags:

views:

250

answers:

3

I'm trying to provide two classes to my users - one that is read-only and one that is writable. The r/o will only have getters, while the writable will inherit from it and add the setters.

I was under the impression that C# should be able to handle it, but the compiler disagreed. Why doesn't this work? Any workarounds?

class A
{
    protected int m_val;
    public int Val
    {
        get { return m_val; }
    }
}

class B : A
{
    public int Val
    {
        set { m_val = value; }
    }
}

class Test
{
    static void Main(string[] args)
    {
        B b = new B();
        b.Val++; // <-- WHY DOESN'T THIS WORK?!
    }
}

P.S. the protected variable in the example above is artificial. My class actually wraps some native resources and the getting/setting happens on either const or mutable native pointer.

+12  A: 

partial applies to a single type - not 2 types (A and B). You would need something more like below, ideally keeping the field private:

class A
{
    private int m_val;
    public int Val
    {
        get { return m_val; }
        protected set { m_val = value; }
    }
}

class B : A
{
    public new int Val
    {
        get { return base.Val;}
        set { base.Val = value; }
    }
}
Marc Gravell
Too slow, yet again. This is exactly what I was going to recommend.
Mark
+1 - just posted mine as a placeholder but you beat me to it
John Rasch
+1  A: 

Mark the setters as protected in the parent, and expose public setters in the child.

Nader Shirazie
+3  A: 

I'm not sure about why you need this, but a possibly better design would be to have two interfaces rather than two classes, and a single class that implements both. Then you could hand your client code whichever interface you'd like them to use, with the added bonus of being able to use the values set on a writable interface and hand it over to someone else as a read-only interface.

Avish
Avish, yeah that would be the obvious thing to do. I need a class (abstract/concrete) because I have internal members that I expect to be there (native pointers). I don't want to expose these, and I don't want to downcast to my class in methods that would expect interface instance.
Filip