从关联的设置类自动创建派生类
本文关键字:创建 派生 设置 关联 | 更新日期: 2023-09-27 18:35:34
我正在尝试根据派生设置类自动实例化正确的派生类。
这里我有一个主基类和一个基设置类
public abstract class BaseClass
{
public BaseClass() { }
public abstract BaseClassSettings Write();
}
public class BaseClassSettings
{
}
现在这里是我的派生类及其设置类
public class DerivedFoo : BaseClass
{
public DerivedFoo(DerivedFooSettings settings)
{
// Apply settings
}
public override BaseClassSettings Write()
{
DerivedFooSettings settings = new DerivedFooSettings();
return settings;
}
}
public class DerivedFooSettings : BaseClassSettings
{
}
public class DerivedBar : BaseClass
{
public DerivedBar(DerivedBarSettings settings)
{
// Apply settings
}
public override BaseClassSettings Write()
{
DerivedBarSettings settings = new DerivedBarSettings();
return settings;
}
}
public class DerivedBarSettings : BaseClassSettings
{
}
我可以将所有派生类设置保存在一个数组中
DerivedFoo foo = new DerivedFoo();
DerivedBar bar = new DerivedBar();
BaseClassSettings[] s = new BaseClassSettings[2];
s[0] = foo.Write();
s[1] = bar.Write();
以 XML 格式序列化为光盘。
如何根据派生设置类自动实例化派生类?
因此,如果数组元素是 DerivedBarSettings 类,则创建 DerivedBar 类的新实例。
我想这样做,而不使用越来越多的 else if 语句,具体取决于类的数量。
if (BaseClassSettings is DerivedFooSettings)
new DerivedFoo(settings)
else if (BaseClassSettings is DerivedBarSettings)
new DerivedBar(settings)
如何做到这一点?
===============================================================================================================================================================================================================================================
[编辑]
这是我正在使用的:
[
XmlInclude(typeof(DerivedSettingsClassA)),
XmlInclude(typeof(DerivedSettingsClassB)),
XmlInclude(typeof(DerivedSettingsClassC)),
XmlInclude(typeof(DerivedSettingsClassD)),
XmlInclude(typeof(DerivedSettingsClassE)),
]
public abstract class BaseSettingsClass
{
public abstract DerivedClass Load(Game1 game, OutputDimensionSettings settings);
}
这样做的唯一缺点是我必须为所有派生类显式定义 XmlInclude。
这是家庭作业吗?
这是一种方法(还有其他可能性):
public abstract class BaseClass
{
public abstract BaseClassSettings Write();
}
public abstract class BaseClassSettings
{
public abstract BaseClass CreateCorrespondingInstance();
}
然后:
public class DerivedFoo : BaseClass
{
public DerivedFoo(DerivedFooSettings settings)
{
// Apply settings
}
public override BaseClassSettings Write()
{
DerivedFooSettings settings = new DerivedFooSettings();
return settings;
}
}
public class DerivedFooSettings : BaseClassSettings
{
public override BaseClass CreateCorrespondingInstance()
{
return new DerivedFoo(this);
}
}
但看起来您可以从泛型中受益!
我不确定泛型在这里会有多大帮助。泛型用于延迟或约束在编译之前未知的类型。您正在做的是在不相关的类型之间创建关系。这可以通过自定义属性和一些反射来完成。
首先是我们的自定义属性:
[System.AttributeUsage(System.AttributeTargets.Class)]
public class BaseClassLinkAttribute : System.Attribute
{
public System.Type LinkedType { get; set; }
public BaseClassLinkAttribute(Type linkedType)
{
// Probably wat to make sure type is derrived from BaseClass
LinkedType = linkedType;
}
}
现在,我们向基类添加一个静态方法,该方法在自定义属性中创建该类型的实例:
public abstract class BaseClass
{
public BaseClass()
{
}
public abstract BaseClassSettings Write();
public static BaseClass CreateFromSettings(BaseClassSettings settings)
{
Attribute attr = Attribute.GetCustomAttribute(settings.GetType(), typeof(BaseClassLinkAttribute));
// Check for null here and throw exception if attribute can't be found in prduction code
BaseClassLinkAttribute linkAttribute = (BaseClassLinkAttribute)attr;
// This is only going to work if class implements a constructor
// that take a base settings class
return (BaseClass)Activator.CreateInstance(linkAttribute.LinkedType,settings);
}
}
现在我们所要做的就是使用我们希望它创建的类的属性标记设置类。
[BaseClassLink(typeof(DerivedFoo))]
public class DerivedFooSettings : BaseClassSettings
{
}
因此,给定一个设置类,我们现在可以创建辅助类:
DerivedFooSettings x = new DerivedFooSettings();
BaseClass y = BaseClass.CreateFromSettings(x);
Console.WriteLine(y.GetType().FullName);
这将为您提供Namespace.DerivedFoo的输出。
当然,这里也有一些限制,派生类必须实现一个采用设置类的构造函数,否则激活将失败。我认为我们的一些工作,你也许能够摆脱attrbiute并使用泛型传递类型。但是,您仍然必须在类型之间创建链接。