Примеры only valid safe , с которыми я сталкивался, более конкретны с типами возвращаемых значений или предоставляют набор методов доступа для свойства. Я не говорю, что это единственные, но это все, что я нашел.
Например, предположим, у вас есть очень простая база, которая выглядит следующим образом:
public abstract class Base
{
public string Name { get; protected set; }
public Base(string name)
{ Name = name; }
}
Вы можете получить производную, которая будет выглядеть примерно так:
public class Derived : Base
{
public new string Name
{
get { return base.Name; }
set { base.Name = value; }
}
public Derived(string name) : base(name)
{ }
}
Предполагая, что бизнес-правила позволяют этому конкретному производному иметь изменяемое имя, я считаю, что это приемлемо. Проблема с new
заключается в том, что он меняет поведение в зависимости от того, как выглядит экземпляр. Например, если бы я сказал:
Derived d = new Derived("Foo");
d.Name = "Bar";
Base b = d;
b.Name = "Baz"; // <-- No set available.
В этом тривиальном примере мы в порядке. Мы переопределяем поведение с new
, но не ломая голову. Изменение типов возвращаемых данных требует немного больше изящества. А именно, если вы используете new
для изменения возвращаемого типа в производном типе, вы не должны позволять этому типу быть установленным базой. Проверьте этот пример:
public class Base
{
public Base(Base child)
{ Child = child; }
public Base Child { get; private set; }
}
public class Derived
{
public Derived(Derived child) : base(child)
{ }
public new Derived Child
{ get { return (Derived)base.Child; } }
}
Если бы я мог set Child
в классе Base
, у меня могла бы быть проблема приведения в классе Derived
. Другой пример:
Derived d = new Derived(someDerivedInstance);
Base b = d;
var c = b.Child; // c is of type Base
var e = d.Child; // e is of type Derived
Я не могу нарушать какие-либо бизнес-правила, рассматривая все мои Derived
классы как базы, просто удобно не проверять и не приводить.