Невозможно привести между общими типами - PullRequest
2 голосов
/ 11 августа 2011

Я пытаюсь сделать это:

interface IA
{
}

class A : IA
{
}

class Foo<T> where T: IA
{
}

class Program
{
    static void Main( string[] args )
    {
        Foo<A> fooA = new Foo<A>();
        Foo<IA> fooIA = fooA as Foo<IA>;
    }
}

Однако приведение с Foo<A> на Foo<IA> не компилируется.Я помню, как видел проблемы с ковариацией при приведении между List<T>, но я не думал, что это применимо к таким простым генерикам.

Что хорошего в том, чтобы заставить этот акт работать?Как мне решить эту проблему?

Ответы [ 4 ]

3 голосов
/ 11 августа 2011

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

Например, через IFoo<out T> или IFoo<in T>

1 голос
/ 11 августа 2011

эти классы выполняют операции с этими базовыми типами, и НИКОГДА их не нужно понижать

Тогда зачем вам Foo<A> для начала? Объявите его как Foo<IA> и добавьте к нему A.

1 голос
/ 11 августа 2011
interface IA
    {
    }

    class A : IA
    {
    }

    interface IFoo<T> where T : IA
    {
    }

    class Foo<T> : IFoo<T> where T : IA
    {
    }

    class Program
    {
        static void Main(string[] args)
        {
            IFoo<A> fooA = new Foo<A>();
            Foo<IA> fooIa = fooA as Foo<IA>;
        }
    }
0 голосов
/ 11 мая 2012

Извините, это в Java, но вы можете сделать что-то вроде этого:

interface Alpha
{
}

class Beta implements Alpha
{
}  

class Foo<T>
{
}

class Program
{
    static void main(string[] args)
    {
        Foo<Beta> fooBeta = new Foo<Beta>();
        Foo<? implements Alpha> fooAlpha = fooBeta;
    }
}

Это не решает проблему полностью, но вы получаете, по крайней мере, доступ ко всем методам Alpha, не зная о Beta ...

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