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;
}
}
}
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
.
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.
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With