KeyedCollection с типом ключа enum не будет индексироваться по int - PullRequest
4 голосов
/ 06 мая 2009

У меня есть классы

public class FooKeyedCollection : KeyedCollection<FooType,Foo>
{
}

public enum FooType
{
   FooType1,
   FooType2,
   FooType3
}

public Foo
{
   public FooType Type { get; set; }
   public string Value { get; set; }
}

Когда я добавляю элементы в свою коллекцию FooKeyedCollection, я могу индексировать их по FooType, но когда я пытаюсь проиндексировать их как int, int интерпретируется как перечисление FooType. В результате это приводит к сбивающей с толку ошибке, т. Е.

public static void main()
{
   FooKeyedCollection fkc = new FooKeyedCollection();

   Foo myFoo = new Foo();
   myFoo.Type = FooType.FooType3;
   myFoo.Value = "someValue";

   foo.Add( myFoo );

   Foo myFooByType = foo[FooType.FooType3];
   Foo myFooByIndex = foo[0]; // <-- exception thrown here
}

Результат выполнения этого кода является исключением при попытке извлечь элемент по целочисленному индексу. Я надеюсь представить FooKeyedCollection как часть общедоступного API, и я хочу защитить потребителей этого API от этой ошибки. Есть ли способ, которым я могу изменить класс FooKeyedCollection, чтобы получить правильное поведение?

Ответы [ 3 ]

3 голосов
/ 06 мая 2009

Вот полезный метод расширения, чтобы избежать этих случаев, когда два индексатора перекрываются - это также помогает, если ключ int:

static class CollectionUtils
{
    public static TValue GetByIndex<TKey,TValue>
        (this KeyedCollection<TKey, TValue> collection, int index)
    {
        return collection[index];
    }
}

затем позвоните fkc.GetByIndex(0) и все будет работать нормально. Внутри общего метода он может только преобразовывать index в индексатор int.

3 голосов
/ 06 мая 2009

Вы можете использовать ключевое слово "new" здесь:

public new Foo this[int index]
{
   get
   {
      IList<Foo> self = this;
      return self[index];
   }
   set
   {
       (IList<Foo>)[index] = value;
   }
}

Это позволит вам индексировать по целому числу. Явное использование перечисления приведет к реализации KeyedCollection.

2 голосов
/ 06 мая 2009

Проблема в том, что 0 неявно преобразуется в FooType. Если вы используете любой другой номер, все будет хорошо. Если вы используете этот код, он тоже должен работать:

int index = 0;
Foo myFooByIndex = foo[index];

РЕДАКТИРОВАТЬ: К сожалению, приведение здесь не помогает - компилятор все еще распознает его как константу 0.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...