Как определить интерфейс или класс с универсальным типом, у которого универсальный тип содержит универсальный тип - PullRequest
0 голосов
/ 27 февраля 2019

Я хочу определить дом с несколькими (специальными и обычными) комнатами, в каждой из которых есть коллекция (специальных и обычных) вещей.

Я начал использовать дженерики для своей коллекции ThingCollection (и производных классов), но когдаЯ хотел определить свои типы комнат. У меня появляются ошибки с определениями моих общих типов.

Кто-нибудь знает правильный способ определения моих интерфейсов / классов, чтобы я не получал это сообщение об ошибке?

Код:

namespace City.Street.House
{
    // Thing(s)
    public interface IThing{ }
    public interface ISpecialThing : IThing { }

    // Collection(s)
    public interface ThingCollection<TThing> where TThing : IThing { }
    public interface SpecialThingCollection<TThing> : ThingCollection<TThing> where TThing : ISpecialThing { }

    // Room(s)  // Error On TThing in both rows below:
    public interface Room<TThingCollection> where TThingCollection : ThingCollection<TThing> { } 
    public interface SpecialRoom<TThingCollection> : Room<TThingCollection> where TThingCollection : SpecialThingCollection<TThing> { }

    // House(s)
    public interface House { }
}

Сообщение об ошибке:

CS0246: Не удалось найти имя типа или пространства имен 'TThing' (вы пропускаете использованиедиректива или ссылка на сборку?)

Ответы [ 2 ]

0 голосов
/ 28 февраля 2019

@ Zohar Ваш хороший ответ заставил меня немного изменить код.

Я использовал эту часть вашего кода:

// Room(s)
public interface Room<TThingCollection> where TThingCollection : ThingCollection<IThing> { }
public interface SpecialRoom<TThingCollection> : Room<TThingCollection> where TThingCollection : SpecialThingCollection<ISpecialThing> { }

Также мне пришлось изменить интерфейсы коллекций на этот:

// Collection(s)
public interface ThingCollection<TThing> where TThing : IThing { }
public interface SpecialThingCollection<TSpecialThing> : ThingCollection<IThing> where  TSpecialThing : ISpecialThing{ }

Без этих изменений коллекции это не сработало бы.

Спасибо за помощь, очень признателен!

0 голосов
/ 27 февраля 2019

Вы не можете использовать TThing в качестве параметра типа в общем ограничении, если оно также не определено также в сигнатуре метода - поэтому Room<TThingCollection> должно стать Room<TThingCollection, TThing> - но для того, чтобы это работало, вам нужно добавить большеограничения:

public interface Room<TThingCollection<TThing>> 
    where TThingCollection : ThingCollection<TThing> 
    where TThing : IThing
{ }

public interface SpecialRoom<TThingCollection<TThing>> : Room<TThingCollection> 
    where TThingCollection : SpecialThingCollection<TThing> 
    where TThing : ISpecialThing
{ }

Или вы можете использовать интерфейсы, которые вы объявили как общие ограничения (измените TThing на IThing и ISpecialThing:

 // Room(s)
public interface Room<TThingCollection> where TThingCollection : ThingCollection<IThing> { }
public interface SpecialRoom<TThingCollection> : Room<TThingCollection> where TThingCollection : SpecialThingCollection<ISpecialThing> { }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...