认为我已经找到了我正在寻找的东西 @Iridium 的答案与我认为将成为我的解决方案的答案很接近,但是我认为我不必将每个项目定义为一个类,我认为我已经找到了一种方法来维护类型安全,并且仍然能够将项目创建为单个基类的属性。
正如@Iridium 的回答一样,它确实需要创建定义分类关系的链接类。
我没有使用接口,而是记得很久以前我发现的一个关于使用受保护构造函数的伪枚举继承的 SO 答案
问题在这里,请参阅“七”的答案
如果我定义了 2 个基类,我可以在这些基类上建立分类链接类
public class ChainEnum
{
public int IntValue { get; protected set; }
public static readonly ChainEnum None = new ChainEnum(1);
protected ChainEnum(int internalValue)
{
this.IntValue = internalValue;
}
}
public class ChainLinkEnum<TParent> : ChainEnum where TParent : ChainEnum
{
public TParent Parent { get; protected set; }
protected ChainLinkEnum(int internalValue, TParent aParent)
: base(internalValue)
{
Parent = aParent;
}
}
然后我可以根据需要使用这些链接尽可能多的层次(对于非常深的树,这可能不理想)
第一级继承自没有父级的链枚举
public class HEBaseMaterial : ChainEnum
{
public static readonly HEBaseMaterial Wood = new HEBaseMaterial(1);
public static readonly HEBaseMaterial Metal = new HEBaseMaterial(1);
protected HEBaseMaterial(int internalValue) : base(internalValue) { }
}
后续级别从定义父级的链链接枚举继承
public class HEWoodItemTypes : ChainLinkEnum<HEBaseMaterial>
{
private static readonly HEBaseMaterial InternalParent = HEBaseMaterial.Wood;
public static readonly HEWoodItemTypes Box = new HEWoodItemTypes(1);
public static readonly HEWoodItemTypes Crate = new HEWoodItemTypes(1);
protected HEWoodItemTypes(int internalValue) : base(internalValue, InternalParent)
{ }
}
public class HEMetalItemTypes : ChainLinkEnum<HEBaseMaterial>
{
private static readonly HEBaseMaterial InternalParent = HEBaseMaterial.Metal;
public static readonly HEMetalItemTypes Box = new HEMetalItemTypes(1);
public static readonly HEMetalItemTypes Bar = new HEMetalItemTypes(1);
protected HEMetalItemTypes(int internalValue) : base(internalValue, InternalParent) { }
}
第三级将使用类似的签名
public class HEThirdLevelType : ChainLinkEnum<HEWoodItemTypes>
设置完成后,我可以定义我的单个基项类,例如:
public class TwoLevelItem<T1,T2>
where T1 : ChainEnum
where T2 : ChainLinkEnum<T1>
{
public T1 LevelOne { get; set; }
public T2 LevelTwo { get; set; }
}
或者如果我想要一个具有 5 个分类级别的项目,每个级别都与之前的一个相关联
public class FiveLevelItem<T1,T2>
where T1 : ChainEnum
where T2 : ChainLinkEnum<T1>
where T3 : ChainLinkEnum<T2>
where T4 : ChainLinkEnum<T3>
where T5 : ChainLinkEnum<T4>
{
public T1 LevelOne { get; set; }
public T2 LevelTwo { get; set; }
public T3 LevelThree { get; set; }
public T4 LevelFour { get; set; }
public T5 LevelFive { get; set; }
}
或 3 个属性,其中一个第一级和 2 个第二级都与第一级相连
public class LinkedItem<T1,T2_1,T2_2>
where T1 : ChainEnum
where T2_1 : ChainLinkEnum<T1>
where T2_2 : ChainLinkEnum<T1>
{
public T1 LevelOne { get; set; }
public T2_1 LevelTwoOne { get; set; }
public T2_2 LevelTwoTwo { get; set; }
}
一旦定义了单个基类,我就可以对其进行反思,并通过链枚举来获得排列。
每个项目都被创建为一个属性
var metalBox = new TwoLevelItem<HEBaseMaterial,HEMetalItemTypes>()
{
LevelOne = HEBaseMaterial.Metal,
LevelTwo = HEMetalItemTypes.Box
}
这保持了类型安全并意味着我可以将新属性添加到分类级别,而不必为项目创建类(尽管我必须生成额外的项目作为属性)
这似乎可以满足我的所有需求,但我还没有广泛尝试。
@Iridium 的答案很接近,但不是我想要的,尽管它确实有帮助。