Reputation: 354
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
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
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
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
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