MajorInc
MajorInc

Reputation: 354

Correct use of C# 'new' modifier to make protected property public

Let's say I have an abstract base class:

public abstract class BaseClass
{
    private MyObject myObject;

    protected MyObject PropA
    {
        get
        {
            if(myObject == null) this.myObject = new MyObject();
            return this.myObject;
        }
    }
}

...and that in one of my derived classes, I want to make the protected base class property PropA public. Would it be correct to use the new modifier in this context?

public class DerivedClass : BaseClass
{
    public new MyObject PropA
    {
        get
        {
            return base.PropA;
        }
    }
}

Upvotes: 5

Views: 3239

Answers (4)

Mertuarez
Mertuarez

Reputation: 944

I would recommend you perhaps

public new string test { 
                          get { return (this as T).test; } 
                          set { (this as T).test = value; } 
                       }

because base give you only parent but if you want to go higher you have to cast.

Upvotes: 0

Olivier Jacot-Descombes
Olivier Jacot-Descombes

Reputation: 112632

The new keyword works and is correct, if you want to add a member in a derived class that has the same name as a member in the base class; however, it seems that this design defies the purpose of abstract classes. Make PropA public and virtual in the base class or public and abstract:

public abstract class BaseClass
{
    // Property not implemented here.
    public abstract MyObject PropA { get; }

    private MyObject _propB;
    // Property implemented, but implementation can be overridden in derived class.
    public virtual MyObject PropB
    {
        get { return _propB ?? (_propB = new MyObject()); }
    }

    public int PropC { get { return 5; } }
}

public class DerivedClass : BaseClass
{
    // You must provide an implementation here.
    private MyObject _propA;
    public override MyObject PropA
    {
        get { return _propA ?? (_propA = new MyObject()); }
    }

    // You are free to override this property and to provide an new implementation
    // or to do nothing here and to keep the original implementation.
    public override MyObject PropB
    {
        get { return <new implementation...>; }
    }

    // PropC is inherited as is and is publicly visible through DerivedClass as well. 
}

Upvotes: 4

Valentin P.
Valentin P.

Reputation: 1151

Would it be correct use of the new modifier in this context?

Technically - yes, there will no errors or warnings.

As for me, using of new keyword itself as a modifier indicates a design drawback.

I'll give one example.

public class MyList<T> : List<T>
{
    public int AddCallsCount;
    public new void Add(T t)
    {
        AddCallsCount++;
        base.Add(t);
    }
}

[TestClass]
public class Test
{
    [TestMethod]
    public void TestThatsNotGood()
    {
        List<object> list = new MyList<object>();
        list.Add(1);
        list.Add(2);

        MyList<object> myList = list as MyList<object>;

        Assert.AreEqual(0, myList.AddCallsCount);

    }
}

It looks like polymorphism works, but actually does not.

UPDATE: Ok, there is very simplified explanation. I omit explanation of what polymorphism is.

Polymorphims is realized with implementation of abstract\virtual and overriding methods. As soon as neither virtual nor override modifiers are specified MyList<T>.Add is just another 'common' public method. And with MyList<T> inherited List<T>, MyList<T>.Add 'hides' List<T>.Add because name and parameters of both methods are same.

At lower level: as soon as List<T> type definition of method Add isn't marked with virtual keyword, compiler won't search for overriding methods of actual instance type (MyList<T> in this certain case) for variable of given type (List<T> in this certain case).

Definetely it may lead to logic errors and incorrect usage of class API.

Hence, compiler 'thinks' that probably there is a logical mistake or design drawback and warns programmer. The new keyword is just a way to talk to the compiler

yes, I know that it's not good, but I need it because of my bad design

.

Upvotes: 4

The Muffin Man
The Muffin Man

Reputation: 20004

That's correct. Anytime you have a class with a member that has the same name as a member in an inherited class you need to use the new keyword (even if the two properties/methods have different return types).

Upvotes: 0

Related Questions