I have two abstract classes that can be inherited for explicit usage: A_GUI_Info and A_Info_Data. The GUI_Infos are GUI elements that display data. The Info_Datas are data classes, that transfer specific data to the according GUI_Info.
I want to express the dependency that an explicit GUI_Info has one explicit Info_Data through generics and still allow an inheritance. With other words, I want to avoid that a wrong explicit Info_Data is fed to an explicit GUI_Info. For example, I feed HUD_Info_Data to a Wrist_GUI_Element that does not have the means to represent it. > A kind of type-safety for inherited generics
Example:
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
Another approach is restrictions by where T : A_GUI_Info<D> where D : A_Info_Data
But it did not work like that.
The final requirement, that I cant get to work is: I have an instance of the explicit Info and want to handle it in a function, that could also handle all other inherited Infos with their according Datas.
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);
}
It may end up that you need to use this kind of data structure:
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; }
}
It's not overly nice, but it does tie the two derived types to each other.
You would defined them like this:
public class HUDInfoData : A_Info_Data<HUDInfoData, HUDInfo>
{
}
public class HUDInfo : A_GUI_Info<HUDInfoData, HUDInfo>
{
}
Have you tried:
abstract class A_Info_Data { ... }
abstract class A_GUI_Info<T> where T: A_Info_Data { ... }
And now:
class CriticalData: A_Info_Data { ... }
class CriticalGui: A_GUI_Info<CriticalData> { ... }
The type parameter on the base class only exists on the base class. The more derived class has to define a new type parameter and pipe through the type to the base class's type parameter. This gives you a place to pose more generic constraints.
For example:
class HUDInfo<THudInfoData> : A_GUI_Info<THudInfoData> where THudInfoData : A_Info_Data
Now, HUDInfo<>
can take any HudInfoData
as long as it derives from A_Info_Data
(or if it is A_Info_Data
). If you wanted to have HUDExtremelySpecificInfo
which could only take HUDExtremelySpecificInfoData
, that would look like:
class HUDExtremelySpecificInfo<THudInfoData> : A_GUI_Info<THudInfoData>
where THudInfoData : HUDExtremelySpecificInfoData
If you never want to specify the type because you know that it will always be HUDExtremelySpecificInfoData
, you can also declare either both:
class HUDExtremelySpecificInfo<THudInfoData> : A_GUI_Info<THudInfoData>
where THudInfoData : HUDExtremelySpecificInfoData { .. }
class HUDExtremelySpecificInfo : HUDExtremelySpecificInfo<HUDExtremelySpecificInfoData> { .. }
(where you implement the non-generic HUDExtremelySpecificInfo
in terms of the generic HUDExtremelySpecificInfo<>
, and can use the generic one if there's a specific even more extremely specific info data subclass that you want to specify)
or just one:
class HUDExtremelySpecificInfo : A_GUI_Info<HUDExtremelySpecificInfoData> { .. }
Thank you all for giving constructive answers. What I try here is not working like preferred (pbbly not possible at all). This is what I came up with:
// 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) { }
For Unity workflow I require the explicit class to be non-generic. So this workaround is possibly the best solution. The drawback: The desired type-safety is not given here.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.