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