我们说我有一个抽象基类:
public abstract class BaseClass
{
private MyObject myObject;
protected MyObject PropA
{
get
{
if(myObject == null) this.myObject = new MyObject();
return this.myObject;
}
}
}
...在我的派生类之一中,我想让受保护的基类属性PropA
公开。在这种情况下使用new
modifier是否正确?
public class DerivedClass : BaseClass
{
public new MyObject PropA
{
get
{
return base.PropA;
}
}
}
答案 0 :(得分:3)
在此上下文中是否正确使用new修饰符?
技术上 - 是的,不会有任何错误或警告。
至于我,使用新关键字本身作为修饰符表示设计缺陷。
我举一个例子。
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);
}
}
看起来多态有效,但实际上并没有。
更新: 好的,有非常简化的解释。我省略了多态性的解释。
使用abstract\virtual
和overriding
方法实现多态变形。只要未指定virtual
和override
修饰符,MyList<T>.Add
只是另一个常见的&#39;}公共方法。 MyList<T>
继承了List<T>
,MyList<T>.Add
&#39;隐藏&#39; List<T>.Add
因为两种方法的名称和参数相同。
在较低级别:只要方法List<T>
的{{1}}类型定义未标记Add
关键字,编译器就不会搜索实际的重写方法实例类型(在这种情况下为virtual
)给定类型的变量(在这种情况下为MyList<T>
)。
定义它可能导致逻辑错误和类API的错误使用。
因此,编译器认为&#39;可能存在逻辑错误或设计缺陷,并警告程序员。 List<T>
关键字只是与编译器交谈的一种方式
是的,我知道它不好,但我需要它,因为我的设计不好
答案 1 :(得分:2)
如果要在派生类中添加与基类中的成员同名的成员,则new
关键字可以正常工作;然而,似乎这种设计违背了抽象类的目的。在基类或公共和抽象中使PropA
公共和虚拟:
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.
}
答案 2 :(得分:0)
这是对的。每当你有一个类的成员与继承类中的成员同名时,你需要使用new关键字(即使这两个属性/方法有不同的返回类型)。
答案 3 :(得分:0)
我可能会推荐您
JSONEncoder
因为dataEncodingStrategy
仅给您父母,但是如果您想更高,就必须投降。