Как передать два похожих конкретных объекта в метод с параметрами интерфейса, которые реализуют обобщения в C #? - PullRequest
5 голосов
/ 19 марта 2012

У меня есть следующие объявления интерфейса:

interface IOrder<T> where T: IOrderItem
{
     IList<T> Items { get; set; }
}

interface IDistro<T> : IOrder<T> where T: IOrderItem
{

}

У меня есть два конкретных класса, например так:

// DistroItem implements IOrderItem
public class Distro : IDistro<DistroItem>
{
    public IList<DistroItem> Items { get; set; }
}

// PerishableOrderItem implements IOrderItem
public class PerishableOrder : IDistro<PerishableOrderItem>
{       
    public IList<PerishableOrderItem> Items { get; set; }
}

Наконец, у меня есть статический метод обслуживания для сохранения в базе данных:

public static void UpdateDistro(IDistro<IOrderItem> distro)
{

}

Моя проблема в том, как передать дистрибутив любого конкретного типа моему статическому методу?Следующее не компилируется:

Distro d = new Distro();
UpdateDistro(d);

Ошибка:

The best overloaded method match for UpdateDistro(IDistro<IOrderItem>)' has some invalid arguments

Является ли контрвариантность ответом?Я попытался добавить <in T> к исходному объявлению интерфейса, но это добавило больше ошибок, которые мне не удалось устранить.Это мое первое углубленное знакомство с интерфейсами, и я уверен, что дженерики увеличивают сложность, поэтому здесь может быть полное отсутствие понимания.

Ответы [ 2 ]

6 голосов
/ 19 марта 2012

Вы пробовали это:

public static void UpdateDistro<T>(IDistro<T> distro) 
  where T : IOrderItem
{  
} 

РЕДАКТИРОВАТЬ:

С пустыми реализациями для классов DistroItem и PerishableItem (оба реализуют IOrderItem), я получилследующая компиляция без ошибки:

Distro d = new Distro();
PerishableOrder p = new PerishableOrder();

UpdateDistro(d);
UpdateDistro(p);
0 голосов
/ 19 марта 2012

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

public interface IOrder<out T> where T : IOrderItem
{
    IEnumerator<T> Items { get; }
}

public interface IDistro<out T> : IOrder<T> where T : IOrderItem
{

}

Чтобы определить T какПараметр cavrient (out), позволяет неявное преобразование классов, которые реализуют ваши варианты интерфейсов.

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