C#.Net 3.5使用具有不同返回类型的重载索引器

Dan*_*Dan 1 c# indexer .net-3.5

我有一个父类,基本上是一个美化的列表.它由各种功能的几个子类扩展.

public class HierarchialItemList<ItemType> : IEnumerable<ItemType>
    {
        public ItemType this[String itemCode]
        {
            get
            {
                foreach (IHierarchialItem curItem in hierarchialItems)
                {
                    if (curItem.Code.Equals(itemCode, StringComparison.CurrentCultureIgnoreCase))
                    {
                        return ((ItemType)curItem);
                    }
                }
                return (default(ItemType));
            }
        }
        public ItemType this[Int32 index]
        {
            get
            {
                return (hierarchialItems[index]);
            }
        }
 }

public class DatabaseList : HierarchialItemList<Database>
{
  public DatabaseList this[CommonDatabaseType typeToFilter]
    {
        get
        {
            DatabaseList returnList = new DatabaseList();
            foreach(Database curDatabase in this)
            {
                if (curDatabase.DatabaseType.Equals(typeToFilter))
                {
                    returnList.Add(curDatabase);
                }
            }
            return (returnList);
        }
    }

    public DatabaseList this[Environments.RMSEnvironment environmentToFilter]
    {
        get
        {
            DatabaseList returnList = new DatabaseList();
            foreach(Database curDatabase in this)
            {
                if (curDatabase.ParentEnvironment.Equals(environmentToFilter))
                {
                    returnList.Add(curDatabase);
                }
            }
            return (returnList);
        }
    }


}
Run Code Online (Sandbox Code Playgroud)

问题是C#认为这个:

Database testDatabase = sampleDatabaseList[0];

是错误,索引器应该返回DatabaseList,而不是数据库.你和我都知道那是假的.任何变通办法或所有索引器都必须具有相同的返回类型?

编辑:我只是想通了,因为使用枚举作为索引器,内部是一个整数.仍然,任何使用枚举和整数的方法?

编辑2:根据要求,这里有一些可用于测试问题的可编译测试代码.

using System;
using System.Collections.Generic;

namespace CSQT
{
    class A<T>
    {
        List<T> temp;

        public A()
        {
            temp = new List<T>();
        }

        public void AddItem(T itemToAdd)
        {
            temp.Add(itemToAdd);
        }

    public T this[String code]
    {
        get { return (temp[0]); }

    }

    public T this[Int32 index]
    {
        get { return (temp[index]); }

    }
}

class B : A<String>
{
    public B()
        : base()
    {
    }

    public B this[BTypes testType]
    {
        get
        {
            return (this);
        }
    }
}

enum BTypes { TEMP1, TEMP2 };

class C
{
    public C()
    {
        B temp = new B();

        //Compile error: Cannot implicitly convert type 'CSQT.B' to 'string'
        String temp2 = temp[0];

        //Compile error: Cannot convert type 'CSQT.B' to 'string'
        String temp3 = (String)temp[0];

        //This compiles and runs but instead of going to A.this[int32], it goes to B.this[BTypes testType]
        B temp4 = temp[0];
    }
}
}
Run Code Online (Sandbox Code Playgroud)

jas*_*son 5

为什么我们知道这是假的?这条线

Database testDatabase = sampleDatabaseList[0];
Run Code Online (Sandbox Code Playgroud)

使用参数0(int文字)调用索引器,因此,看到DatabaseList继承自HierarchialItemList<Database>将调用由其定义的索引器

public ItemType this[Int32 itemCode] { get; }
Run Code Online (Sandbox Code Playgroud)

声明返回的ItemType.你还没告诉我们是什么ItemType.我们没有理由知道ItemType可以将a赋值给类型的变量Database.

索引器不必返回相同的类型.但是,不能仅根据返回类型超载.也就是说,这是合法的

class IndexerTest {
    public int this[int index] {
        get {
            return 0;
        }
    }

    public string this[double index] {
        get {
            return "Hello, success!";
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这不是

class IndexerTest {
    public int this[int index] {
        get {
            return 0;
        }
    }

    public string this[int index] {
        get {
            return "Hello, fail!";
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

回应你的编辑:

编辑:我只是想通了,因为使用枚举作为索引器,内部是一个整数.仍然,任何使用枚举和整数的方法?

如果要调用接受枚举的索引器,请像这样调用它:

sampleDatabaseList[Environments.RMSEnvironment.SomeEnumValue];
Run Code Online (Sandbox Code Playgroud)