C# 抽象类C中嵌套泛型/嵌套泛型的继承#

C# 抽象类C中嵌套泛型/嵌套泛型的继承#,c#,generics,abstract,C#,Generics,Abstract,我有两个抽象类可以被继承以供显式使用:一个是GUI\u Info,一个是Info\u Data。GUI信息是显示数据的GUI元素。Info_数据是数据类,用于将特定数据传输到相应的GUI_信息 我想表达一种依赖关系,即显式GUI\u Info通过泛型拥有一个显式Info\u数据,并且仍然允许继承。换句话说,我希望避免将错误的显式信息数据提供给显式GUI信息。例如,我将HUD\U Info\U数据提供给一个手腕GUI\U元素,该元素没有表示它的方法。>继承泛型的一种类型安全性 例如: class

我有两个抽象类可以被继承以供显式使用:一个是GUI\u Info,一个是Info\u Data。GUI信息是显示数据的GUI元素。Info_数据是数据类,用于将特定数据传输到相应的GUI_信息

我想表达一种依赖关系,即显式GUI\u Info通过泛型拥有一个显式Info\u数据,并且仍然允许继承。换句话说,我希望避免将错误的显式信息数据提供给显式GUI信息。例如,我将HUD\U Info\U数据提供给一个手腕GUI\U元素,该元素没有表示它的方法。>继承泛型的一种类型安全性

例如:

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
class HUDInfoData:A_Info_数据
类HUDInfo:A_GUI_Info
//但是通用的语言不能像那样被继承
类HUDInfo:A_GUI_Info
//不定义依赖关系
类HUDInfo:A_GUI_Info
//也不起作用
另一种方法是通过
进行限制,其中T:A_GUI_Info,其中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);
}
公共HUD\u信息对象;
公开名单信息;
public void SetConnection(字符串ID,A_GUI_Info p)
{
添加(p);
}
您是否尝试过:

abstract class A_Info_Data { ... }
abstract class A_GUI_Info<T> where T: A_Info_Data { ... }
抽象类A\u信息\u数据{…}
抽象类A_GUI_Info其中T:A_Info_Data{…}
现在:

class CriticalData: A_Info_Data { ... }
class CriticalGui: A_GUI_Info<CriticalData> { ... }
class CriticalData:A_Info_Data{…}
类CriticalGui:A_GUI_Info{…}

基类上的类型参数仅存在于基类上。更派生的类必须定义一个新的类型参数,并通过该类型传递到基类的类型参数。这为您提供了一个设置更通用约束的位置

例如:

class HUDInfo<THudInfoData> : A_GUI_Info<THudInfoData> where THudInfoData : A_Info_Data
如果您永远不想指定类型,因为您知道它将始终是
hudetremelyspecificinfodata
,您还可以声明以下两种类型之一:

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

class HUDExtremelySpecificInfo : HUDExtremelySpecificInfo<HUDExtremelySpecificInfoData> { .. }

最终可能需要使用这种数据结构:

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; }
}
公共抽象类A\u GUI\u信息
其中G:A\u信息\u数据
其中D:A_GUI_Info
{
公共G Gui{get;set;}
}
公共抽象类A\u信息\u数据
其中G:A\u信息\u数据
其中D:A_GUI_Info
{
公共数据{get;set;}
}
这并不太好,但它确实将两个派生类型相互联系起来

您可以这样定义它们:

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

public class HUDInfo : A_GUI_Info<HUDInfoData, HUDInfo>
{
}
公共类HUDInfoData:A_Info_数据
{
}
公共类HUDInfo:A_GUI_Info
{
}

感谢大家给出建设性的答案。我在这里尝试的不是像preferred那样工作(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工作流,我要求显式类是非泛型的。因此,这种变通方法可能是最好的解决方案。缺点:这里没有给出所需的类型安全性。

是的,但是您不会对类型参数
THudInfoData
施加约束,即无论您在那里传递什么,都必须是
huderemelysspecificinfodata
或其子类,我认为这是整个练习的重点。这看起来是正确的方法。但是我想使用显式类组合作为函数参数:SetConnection(string ID,GUI_Info元素),但是我在相应地定义函数泛型时遇到了问题,因此函数将与每个显式创建一起工作。在方法的参数列表中,每当有泛型类型参数,您必须将其固定到位(
List
),或者在包含类型中或在您可以引用的方法上有一个类型参数(
List
,为方法或类型本身定义了
T
).但这是毫无意义的:
类hudextremelysspecificinfo:A_GUI_Info,其中THudInfoData:hudextremelysspecificinfodata
。为什么不简单地
类hudevermelyspecificinfo:A_GUI_Info
?这是我最初的评论。我不明白为什么
hudetremelyspecificinfo
必须是泛型的。这是有意义的,因为这个问题似乎暗示可能有很多子类。如果有两个或三个更具体的infodata类,则可以将其中一个作为泛型参数传递。如果只有一个,严格来说,你不需要其他任何东西,除了底部的那个。这就是为什么我编辑了我的答案,将两者都提到。这个答案并不能直接解决我的问题。然而,在许多情况下,包装整个过程并将元素作为变量公开将是一个健壮的解决方案。
public class HUDInfoData : A_Info_Data<HUDInfoData, HUDInfo>
{
}

public class HUDInfo : A_GUI_Info<HUDInfoData, HUDInfo>
{
}
// 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) { }