2009-09-24 66 views
1

在层次结构中,在某个点使用new关键字来覆盖方法中的返回类型是否正常?C#中的新操作符和虚拟操作符

我可以使用virtual newnew virtual,这样我可以重写返回类型吗?

我还需要考虑从那个点继承的类。他们可以重写这种方法,其基地是用new创建的?

回答

14

可以这样做,但真正的问题是你是否应该做到这一点。

问题是,你会得到非常意想不到的行为,这取决于你的类如何使用。如果你从基类的一个实例中调用你的类,原始的非“新”方法将被调用,这可能是意想不到的。

一般来说,我会避免使用new关键字来覆盖基类方法,除非有非常明确的理由这样做 - 如果您的方法将返回一个新类型,请将其声明为一个新方法一个不同的名称或签名,而不是隐藏基类方法 - 它会使您的层次更加可用。

+1

我完全同意。你应该有一个非常有说服力的理由这样做。继承关系是“IS A”关系,所以如果A从B继承,那么A就是B.这意味着A也应该表现得好像它是B. – Pete 2009-09-24 17:21:36

+0

我完全同意你的看法。我这样做的原因是因为我正在使用遗留代码:(它是这样做的,我可以改变它,我也不喜欢它,但我也是,我现在唯一确定的是它将使用所有将使用新类的地方,至少从声明“新”类的地方调用 – jmayor 2009-09-24 17:43:08

+0

正如我所说,你可以这样做 - 我个人会建议切换方法名,特别是尽管如此,避免这种情况,它使生活非常混乱。 – 2009-09-24 17:53:36

0

打趣....

public class BaseCollection<T> 
{ 
    // void return - doesn't seem to care about notifying the 
    // client where the item was added; it has an IndexOf method 
    // the caller can use if wants that information 
    public virtual void Add(T item) 
    { 
    // adds the item somewhere, doesn't say where 
    } 

    public int IndexOf(T item) 
    { 
    // tells where the item is 
    } 
} 

public class List<T> : BaseCollection<T> 
{ 
    // here we have an Int32 return because our List is friendly 
    // and will tell the caller where the item was added 
    new public virtual int Add(T item) // <-- clearly not an override 
    { 
    base.Add(item); 
    return base.IndexOf(item); 
    } 
} 

这里我使用了“新”的修改,因为列表<牛逼>参考将从BaseCollection <牛逼>隐藏Add方法。默认情况下,隐藏基本成员会从编译器生成警告(如果编译设置为警告失败,则为错误)。所以我基本上是在告诉编译器......“是的,我知道我使用void return隐藏了Add方法,它是所需的功能 - 只需要使用它。”