Как решить ошибку дженериков CS0311?

Я искал в Интернете и stackoverflow и нашел много сообщений, посвященных ошибке CS0311. Ни один из сценариев мне не близок. У меня есть универсальный класс, который наследуется от универсального класса.

Обратите внимание, что BusinessBase — это класс в фреймворке CSLA.

Что мне не хватает?

public interface Itest
{
    int Digit();
}

class BB : Itest
{
    public int Digit()
    {
        return 20;
    }
}


class Test<T> : BusinessBase<T>, Itest where T : Test<T>, Itest
{
    public int Digit()
    {
        return 30;
    }
}

Test<Itest> test = new Test<Itest>(); //error CS0311

Ошибка CS0311 Тип 'MyTestApp.Itest' нельзя использовать в качестве параметра типа 'T' в универсальном типе или методе 'A<T>'. Нет неявного преобразования ссылок из 'MyTestApp.Itest' в 'MyTestApp.A<MyTestApp.Itest>'. MyTestApp


person Bill    schedule 10.01.2017    source источник
comment
Вам не нужен бит Test<T> в предложении where, попробуйте where T : Itest   -  person Hywel Rees    schedule 10.01.2017
comment
каждый Test<T> является Itest, но каждый Itest не является Test<T>, поэтому он терпит неудачу (точно так же, как BB у вас есть. Itest может быть BB)   -  person M.kazem Akhgary    schedule 10.01.2017


Ответы (2)


Вы можете сделать что-то вроде этого:

interface Itest {}

class BusinessBase<T> {

}

class Test<T> : BusinessBase<T>, Itest where T : Test<T>, Itest {
    public int Digit() {
        return 30;
    }
}

class IT : Test<IT>, Itest {

}

class Program {
    public static int Main() {

        var t = new Test<IT>();
        t.Digit();
        return 0;
    }
}

Что для меня действительно ужасное использование дженериков, но именно так работает CSLA....

person Alejandro Miralles    schedule 10.01.2017
comment
Спасибо. Я бы дал вам голос, но я новый пользователь и не имею достаточных привилегий. Сделаю, как только приобрету :) - person Bill; 10.01.2017

Я согласен с компилятором. T в вашем сценарии Itest. Ваше условие where требует, чтобы T : Test<T> (что сразу звучит подозрительно), что потребовало бы этого ITest : Test<ITest> ... но ITest явно не требует (и не может) : Test<ITest>.

Очень-очень неясно, что вы намеревались сделать, но я подозреваю, что вы имеете в виду:

class Test<T> where T : Itest

и:

Test<BB> test = new Test<BB>();
person Marc Gravell    schedule 10.01.2017
comment
Я отредактировал свой код. Я наследую объект CSLA. Если я не включу Test‹T› в ограничения, я получу ошибку определения класса. - person Bill; 10.01.2017