Наследование вложенных шаблонов / вложенных шаблонов в абстрактном классе C# - PullRequest
2 голосов
/ 30 марта 2020

У меня есть два абстрактных класса, которые могут быть унаследованы для явного использования: A_GUI_Info и A_Info_Data. GUI_Infos - это элементы GUI, которые отображают данные. Info_Datas - это классы данных, которые передают определенные c данные в соответствующий GUI_Info.

Я хочу express зависимость, что явный GUI_Info имеет один явный Info_Data через дженерики и все еще допускает наследование. Другими словами, я хочу избежать того, чтобы неправильные явные Info_Data передавались явному GUI_Info. Например, я передаю HUD_Info_Data элементу Wrist_GUI_Element, у которого нет средств для его представления. > Тип безопасности типов для унаследованных обобщений

Пример:

class HUDInfoData : A_Info_Data
class HUDInfo<HUDInfoData > : A_GUI_Info<A_Info_Data> 
// but the generic cant be inherited like that

class HUDInfo : A_GUI_Info<A_Info_Data>
// doesnt define dependency

class HUDInfo : A_GUI_Info<HUDInfoData >
// also not working

Другой подход - ограничения по where T : A_GUI_Info<D> where D : A_Info_Data Но это не сработало.

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

public HUD_Info<HUD_Info_Data> obj;

public List<A_GUI_Info<A_Info_Data>> infos;

public void SetConnection(string ID, A_GUI_Info<A_Info_Data> p)
{
    infos.Add(p);
}

Ответы [ 4 ]

0 голосов
/ 30 марта 2020

Спасибо всем за конструктивные ответы. То, что я пытаюсь здесь, не работает, как предпочитаемый (pbbly вообще невозможно). Вот что я придумал:

// abstract definitions
public abstract class AInfo
{
    public abstract void SetData(AInfoData data);
}
public abstract class AInfoData

// explicit definitions
public class WristInfo : AInfo
{
    public override void SetData(AInfoData data)
    {
        Data_Info_Wrist d = (Data_Info_Wrist)data; // cast to use
    }
}
public class Data_Info_Wrist : AInfoData

// runtime usage
public AInfo instance; (WristInfo)

public void Setup(AInfo info) { }

Для рабочего процесса Unity я требую, чтобы явный класс не был универсальным c. Так что этот обходной путь, возможно, является лучшим решением. Недостаток: требуемая безопасность типов здесь не указана.

0 голосов
/ 30 марта 2020

Параметр типа в базовом классе существует только в базовом классе. Более производный класс должен определить новый параметр типа и направить через тип к параметру типа базового класса. Это дает вам место для более общих ограничений c.

Например:

class HUDInfo<THudInfoData> : A_GUI_Info<THudInfoData> where THudInfoData : A_Info_Data

Теперь HUDInfo<> может занять любое HudInfoData, если оно получается из A_Info_Data (или если равно A_Info_Data). Если вы хотите иметь HUDExtremelySpecificInfo, который может принимать только HUDExtremelySpecificInfoData, это будет выглядеть так:

class HUDExtremelySpecificInfo<THudInfoData> : A_GUI_Info<THudInfoData>
    where THudInfoData : HUDExtremelySpecificInfoData

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

class HUDExtremelySpecificInfo<THudInfoData> : A_GUI_Info<THudInfoData>
    where THudInfoData : HUDExtremelySpecificInfoData { .. }

class HUDExtremelySpecificInfo : HUDExtremelySpecificInfo<HUDExtremelySpecificInfoData> { .. }

(где вы реализуете non-generi c HUDExtremelySpecificInfo в терминах generi c HUDExtremelySpecificInfo<>, и можете использовать generi c один, если есть специфицированный c, еще более чрезвычайно специфичный c информационный подкласс данных, который вы хотите указать)

или только один:

class HUDExtremelySpecificInfo : A_GUI_Info<HUDExtremelySpecificInfoData> { .. }
0 голосов
/ 30 марта 2020

Может случиться так, что вам понадобится использовать такую ​​структуру данных:

public abstract class A_GUI_Info<G, D>
    where G : A_Info_Data<G, D>
    where D : A_GUI_Info<G, D>
{
    public G Gui { get; set; }
}

public abstract class A_Info_Data<G, D>
    where G : A_Info_Data<G, D>
    where D : A_GUI_Info<G, D>
{
    public D Data { get; set; }
}

Это не слишком приятно, но это делает ie два производных типа друг для друга.

Вы бы определили их так:

public class HUDInfoData : A_Info_Data<HUDInfoData, HUDInfo>
{
}

public class HUDInfo : A_GUI_Info<HUDInfoData, HUDInfo>
{
}
0 голосов
/ 30 марта 2020

Вы пробовали:

abstract class A_Info_Data { ... }
abstract class A_GUI_Info<T> where T: A_Info_Data { ... }

А сейчас:

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