Приведите простой объект к простому и универсальному интерфейсу - PullRequest
0 голосов
/ 06 мая 2018

Я ищу способ приведения объекта к простому интерфейсу и к универсальному интерфейсу, который вытекает из простого.

Вот мой пример:

interface INonGeneric
{

}

interface IGeneric<T> : INonGeneric where T : ITypeParameter
{
    T Build();
}

interface ITypeParameter
{

}

class TypeClass : ITypeParameter
{

}

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

Затем я создаю классы, которые хочу использовать:

class MyClass : MyClassBase<TypeClass>
{
    public override TypeClass Build()
    {
        return new TypeClass();
    }
}

abstract class MyClassBase<T> : IGeneric<T> where T : ITypeParameter
{
    public abstract T Build();
}

А потом я пытаюсь разыграть их так:

void Main()
{
    var myClass = new MyClass();

    var cast1 = myClass as INonGeneric;
    if(cast1 != null) Console.WriteLine("cast 1 works!"); //THIS WORKS
    var cast2 = TestCast<ITypeParameter>(myClass);
    if(cast2 != null) Console.WriteLine("cast 2 works!"); //THIS DOES NOT WORK
}

Любая помощь будет принята с благодарностью.

edit: извините, я забыл поместить в метод TestCast. Вот оно:

IGeneric<T> TestCast<T>(INonGeneric obj) where T : ITypeParameter
{
    return obj as IGeneric<T>;
}

1 Ответ

0 голосов
/ 06 мая 2018

Это не работает из-за заботы о Ковариантности. Рассмотрим этот пример кода.

var liInt = new List<int>() { 1,2,3};
var liObj = List<object>(liInt);

После этого вы можете серьезно добавить не целочисленное значение в liObj, и, очевидно, это не так.

bool b = false;
liObj.Add(b);

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

interface IGeneric<out T> : INonGeneric where T : ITypeParameter

Для получения дополнительной информации, пожалуйста, смотрите ссылку ниже: http://tomasp.net/blog/variance-explained.aspx/

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