6

可能重复:
属性声明中的“new”关键字

如果这是 C# 101,请原谅我,但我试图理解下面的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace Generics
{
    class RabbitCollection : ArrayList
    {
        public int Add(Rabbit newRabbit)
        {
            return base.Add(newRabbit);
        }

        //collections indexer 
        public new Rabbit this[int index]
        {
            get { return base[index] as Rabbit; }
            set { base[index] = value; }
        }
    }
}

为什么索引器new前面有?顺便说一句,Rabbit 是在另一个文件中定义的类。谢谢!

4

4 回答 4

6

尝试从代码中删除 new ,您应该会收到警告:

RabbitCollection.this[int]'隐藏继承的成员 'System.Collections.ArrayList.this[int]'。要使当前成员覆盖该实现,请添加 override 关键字。否则添加新关键字。

您可能希望看到新的修饰符 C#

new 关键字显式隐藏了从基类继承的成员。当您隐藏继承的成员时,该成员的派生版本将替换基类版本。尽管您可以在不使用 new 修饰符的情况下隐藏成员,但结果是警告。如果您使用 new 显式隐藏成员,它会抑制此警告并记录派生版本旨在作为替换的事实。

于 2012-07-27T03:24:33.003 回答
4

因为基类 ( ArrayList) 也有一个索引器。上面写着“new我故意用我自己的一个替换基类成员。”

它在没有 的情况下也可以工作new,但是new告诉编译器你知道你在做什么。

当然,在过去七八年的任何时间编写的代码中,您应该使用List<T>代替ArrayList,然后您不需要使用自己的强类型索引器创建后代。

于 2012-07-27T03:25:31.460 回答
4

这是因为这个类隐藏了基类的一个成员(ArrayList 也定义了相同的索引器)。

New 告诉编译器这种行为是有意的而不是错误的。

阅读c# 多态性指南

用新的派生成员替换基类的成员需要 new 关键字。如果基类定义了方法、字段或属性,则 new 关键字用于在派生类上创建该方法、字段或属性的新定义。new 关键字放在被替换的类成员的返回类型之前。

于 2012-07-27T03:26:30.510 回答
1

通常,如果一个基类型打算重写一个方法,它将被标记为虚拟的。在这种情况下,子类型只是用覆盖标记方法。

如果基类型没有,而子类型定义了相同的方法,则存在歧义。C# 编译器要求您通过用 new 标记子类型方法来确认您想要这个 - 实际上是说“是的,我知道并且我想隐藏基类型提供的方法”

于 2012-07-27T03:27:40.350 回答