Как использовать интерфейс в качестве общего параметра? - PullRequest
0 голосов
/ 30 апреля 2018

У меня есть общий класс:

class JobDetails<IJobRequirement>{}
class SpecialRequirement: IJobRequirement{}

Я не могу присвоить значения типа JobDetails<SpecialRequirement> переменным типа JobDetails<IJobRequirement>. Это возможно в C # или я что-то упустил?

Ответы [ 2 ]

0 голосов
/ 30 апреля 2018

Обычно Foo<A> и Foo<B> не имеют общего происхождения. Они имеют общее определение универсального типа, но это не означает, что они могут быть назначены, даже если public class B : A.

Вы, кажется, ищете Co- и Contravariance. Механизм для обобщений в C #, который позволяет определять совместимость между различными типами. Однако это работает только для универсальных интерфейсов.

Например

public interface IJobDetails<out TRequirement>
   where TRequirement : IJobRequirement
{
    TRequirement Requirement { get; }
}

public class JobDetails<TRequirement> : IJobDetails<TRequirement>
{
    public TRequirement Requirement { get; set; }
}

public void Test()
{
    IJobDetails<IJobRequirement> a = new JobDetails<SpecificRequirement>();
}

Однако использование модификатора in или out ограничивает возможность использования типа only в качестве возвращаемого значения или в качестве аргумента метода.

По этой причине вы присваиваете IEnumerable<B> IEnumerable<A>, если public class B : A, потому что IEnumerable объявлен как IEnumerable<out T>.

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

0 голосов
/ 30 апреля 2018

Вы можете наложить ограничения на параметры типа :

interface IJobRequirement
{ }

class SpecialRequirement : IJobRequirement
{ }

class JobDetails<T> where T : IJobRequirement
{ }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...