Неуниверсальный интерфейс как синоним родового - PullRequest
2 голосов
/ 27 октября 2010

У меня есть один универсальный интерфейс в c #, и почти всегда я использую его с одним из типов. Я хочу создать неуниверсальный интерфейс для этого типа и использовать его.

Допустим, у меня есть следующий код:

public interface IMyGenericList<out T> where T : IItem
{
    IEnumerable<T> GetList();
}

public class MyList<T> : IMyGenericList<T> where T : IItem
{
    public IEnumerable<T> GetList()
    {
        return null;
    }
}

это хорошо работает. В большинстве случаев мне нужно IMyGenericList<IItem>, поэтому я пробую следующее:

public interface IMyItemsList : IMyGenericList<IItem>
{
}

но по какой-то причине я не могу заставить MyList реализовать IMyItemsList. Следующий код возвращает ошибку

public class MyList<T> : IMyItemsList, IMyGenericList<T> where T : IItem
{
    public IEnumerable<T> GetList()
    {
        return null;
    }
}

сказав, что IEnumerable<IItem> is not implemented.

Почему это так / что я могу с этим сделать? Спасибо.

Хорошо, благодаря вашим ответам я понял, что невозможно сделать это именно так, как я хотел изначально. Я опубликую еще один вопрос о том, почему это невозможно :) Вот оно: Одна функция, реализующая универсальный и неуниверсальный интерфейс

Ответы [ 2 ]

2 голосов
/ 27 октября 2010

Ваш конкретный пример не сработает, поскольку ваш класс:

public class MyList<T> : IMyItemsList, IMyGenericList<T> where T : IItem
{
  public IEnumerable<T> GetList()
  {
    return null;
  }
}

пытается реализовать и IEnumerable<IItem> GetList(), и IEnumerable<T> GetList(), что является двумя разными вещами.Это первое явно перечислимое значение IItem (как того требует ваш IMyItemsList интерфейс), а второе перечисляемое значение T.

В этом сценарии T имеет тип IItem, но не явно IItem.Поэтому во время компиляции IEnumerable<IItem> GetList() не является IEnumerable<T> GetList(), поэтому компилятор правильно выдаст ошибку, сообщающую, что IEnumerable<IItem> GetList() не реализован.

Другая проблема, с которой вы столкнетесь, - это то, что происходит, когдакто-то делает:

var list = new MyList<IItem>();

Компилятор попытается создать конкретную реализацию MyList<IItem>, которая будет иметь два определения IEnumerable<IItem> GetList().

Я бы пересмотрел ваш дизайн для оценкиединственное число IEnumerable<T> GetList().

Кроме того, и просто требователен с моей стороны: "enumerable"! = "list": P

1 голос
/ 27 октября 2010

Ваш интерфейс IMyItemsList не может быть унаследован от интерфейса IMyGenericList<out T>, если вы хотите, чтобы MyList<T> реализовал их оба. Но вы можете изменить интерфейс IMyItemsList, как указано ниже:

public interface IItem
{
}

public interface IMyItemsList
{
    IEnumerable<IItem> GetList();
}

public interface IMyGenericList<out T> where T : IItem
{
    IEnumerable<T> GetList();
}

public class MyList<T> : IMyGenericList<T>, IMyItemsList 
    where T : IItem
{
    public IEnumerable<T> GetList()
    {
        return null;
    }

    IEnumerable<IItem> IMyItemsList.GetList()
    {
        return this.GetList().Cast<IItem>();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...