Ковариация не работает с общей записью словаря - PullRequest
1 голос
/ 10 июля 2011

Учитывая класс ниже:

public class ConcreteEmployeeRoleCreator<T, TConcrete, TSpec> 
    where TConcrete : class, T, new()
    where T : EmployeeRole
    where TSpec : EmployeeRoleSpecification
{
    public ConcreteEmployeeRoleCreator(TSpec spec) { Specification = spec; }

    public TSpec Specification { get; private set; }

    public T Create() { return new TConcrete(); }

}

Я хотел бы иметь словарь «создателей», но я пока не смог понять, как это сделать.Если я попытаюсь определить словарь, используя наименьший общий тип знаменателя, компилятор не разрешит добавить экземпляр

[Test]
public void Creator_CanCreateFromSpec() {
    var creators = new Dictionary<string, ConcreteEmployeeRoleCreator<EmployeeRole, EmployeeRole, EmployeeRoleSpecification>>();
    var spec = new SalesmanRoleSpecification();
    var creator = new ConcreteEmployeeRoleCreator<EmployeeRole, Salesman, SalesmanRoleSpecification>(spec);
    creators.Add("salesman", creator); <==== ** compile error **
}

Продавец равен EmployeeRole, а SalesmanRoleSpecification равен a EmployeeRoleSpecification (или я не смог бы определить создателя выше без ошибки компилятора).

ТАК Я полагаю, это способ объявления словаря?Что я делаю не так?

Ура,
Беррил

1 Ответ

3 голосов
/ 10 июля 2011

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

Итак, учитывая, что вы используете класс,

ConcreteEmployeeRoleCreator<EmployeeRole, Salesman, SalesmanRoleSpecification>

никогда не будет

ConcreteEmployeeRoleCreator<EmployeeRole, EmployeeRole, EmployeeRoleSpecification>

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

...