Проблема ковариации интерфейсов - PullRequest
0 голосов
/ 07 сентября 2010

Так что у меня есть такой код.

public interface IGeoDataSet<out T> : IDataSet
    where T : IGeoPrimitive<IGeoPrimitiveContent>
{
    IEnumerable<T> Items { get; } 
}

public interface IDataSet { }

public interface IGeoPrimitive<T> : IPrimitive
    where T : IGeoPrimitiveContent
{
    T Content { get; }
}

public interface IPrimitive { }

public interface IGeoPrimitiveContent { }

И такое дополнение для предыдущих интерфейсов.

public class TriangleDataSet : IGeoDataSet<Triangle>
{
    public IEnumerable<Triangle> Items { get; private set; }
}

public class Triangle : IGeoPrimitive<TriangleContent>
{
    public TriangleContent Content { get; private set; }
}

public class TriangleContent : IGeoPrimitiveContent { }

Когда я пытаюсь скомпилировать этот код, у меня появляется ошибка:

The type '.Triangle' cannot be used as type parameter 'T' in the generic type or method '.IGeoDataSet<T>'. There is no implicit reference conversion from '.Triangle' to '.IGeoPrimitive<.IGeoPrimitiveContent>'.

Я не могу понять, почему, может быть, кто-то знает, в чем проблема?

Br, Jevgenij

Ответы [ 3 ]

1 голос
/ 07 сентября 2010

Вам необходимо, чтобы ваш IGeoPrimitive<T> интерфейс также был ковариантным, чтобы можно было использовать Triangle в качестве параметра типа для реализации IGeoDataSet<out T>:

// Note addition of 'out' keyword
public interface IGeoPrimitive<out T> : IPrimitive
    where T : IGeoPrimitiveContent
{
    T Content { get; }
}

Это потому, что у вас есть ограничение where T : IGeoPrimitive<IGeoPrimitiveContent>;но без IGeoPrimitive<T>, являющегося ковариантным, Triangle (который реализует IGeoPrimitive<TriangleContent>) не удовлетворяет этому ограничению.

0 голосов
/ 07 сентября 2010

Вам лучше объявить свои интерфейсы как:

public interface IGeoDataSet<out T, out V> : IDataSet
    where T : IGeoPrimitive<V>
    where V : IGeoPrimitiveContent
{
    IEnumerable<T> Items { get; } 
}

и

public interface IGeoPrimitive<out T> : IPrimitive
    where T : IGeoPrimitiveContent
{
    T Content { get; }
}
0 голосов
/ 07 сентября 2010

Вы должны объявить IGeoPrimitive<T> ковариант:

public interface IGeoPrimitive<out T> : IPrimitive
    where T : IGeoPrimitiveContent
{
    T Content { get; }
}
...