为什么这段代码在集合索引器中使用了new关键字?

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 是另一个文件中定义的类。谢谢!

我会使用C风格的转换而不是安全转换。现在把它扔掉,使用List<T> - Ed S.
4个回答

6
尝试在代码中去掉 new,你应该会得到一个警告:
RabbitCollection.this[int]' 隐藏了继承的成员 'System.Collections.ArrayList.this[int]'。若要使当前成员覆盖该实现,请添加 override 关键字。否则,请添加 new 关键字。
你可能想查看 C# 中的 new 修饰符 new 关键字明确隐藏从基类继承的成员。当您隐藏继承的成员时,派生版本的成员替换基类版本。虽然您可以在不使用 new 修饰符的情况下隐藏成员,但结果是一个警告。如果您使用 new 明确隐藏成员,则会抑制此警告并记录派生版本旨在替换的事实。

哇,大家的回应真快!这是很棒的信息。谢谢你们! - Irfarino

4
因为基类(ArrayList)也有一个索引器。 new表示“我故意用自己的成员替换了基类成员”。
没有new也可以工作,但new告诉编译器你知道自己在做什么。
当然,在过去的七八年中编写的代码中,应该使用List<T>而不是ArrayList,这样就不需要创建具有自己强类型索引器的后代了。

4
这是因为这个类隐藏了基类的一个成员(ArrayList也定义了相同的索引器)。
使用new关键字告诉编译器这种行为是有意的,而不是错误。
阅读c#多态指南 引用块: 替换基类成员为新的派生成员需要使用new关键字。如果基类定义了一个方法、字段或属性,则使用new关键字在派生类上创建该方法、字段或属性的新定义。new关键字放置在被替换的类成员的返回类型之前。

谢谢!指向多态性指南的指针 - Irfarino

1
通常,如果基类型打算重写方法,则会将其标记为虚拟的。在这种情况下,子类型只需使用override标记该方法即可。
如果基类型没有这样做,而子类型定义了相同的方法,则存在歧义。C#编译器会要求您通过使用new标记子类型方法来确认您想要这样做-实际上是说“是的,我知道并且我想隐藏基类型提供的方法”。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接