c# - 在工厂中自动注册构造函数
问题描述
我有一个基类 DataSet 和几个派生类(DataSetSeries、DataSetTable、...)。派生类的构造函数每个都只接受一个参数,其类型特定于派生类,例如
public DataSetSeries(Series s);
public DataSetTable(Table t);
我编写了一个(通用)工厂类,它允许我从相应的原始数据类型创建 DataSet 子类的实例,例如
DataSet aDataSetSeries = DataSet.Factory.Create(aSeries);
DataSet aDataSetTable = DataSet.Factory.Create(aTable);
其中 DataSet.Factory 是 DataSet 的静态只读字段。Create 所做的是确定其参数的类型,然后尝试从字典中查找相应的构造函数委托(之前已注册)并执行委托(如果存在)。
所以我必须在工厂注册每个派生类的构造函数。为了将相似的东西放在一起并且不要忘记为任何新的 DataSet 子类添加注册,我想在派生的 DataSet 类而不是 DataSet 本身中进行注册(它不应该知道它的任何派生严格的面向对象意义上的类)。因为 Factory 是静态的,所以我试图在每个派生的 DataSet 中包含一个静态构造函数,例如
public class DataSetSeries: DataSet
{
static DataSetSeries()
{
Factory.Register(typeof(Series), data => new DataSetSeries((Series)data));
}
// ...
}
但现在这是我的问题:DataSetSeries 的静态构造函数只会在第一次使用 DataSetSeries 时被调用。但是我要做的第一件事是调用 DataSet.Factory.Create(aSeries),它不是 DataSetSeries 的方法,所以根本没有第一次使用 DataSetSeries。因此永远不会调用静态构造函数。
如果不明确地迭代所有派生类型(这就是首先设置工厂的原因),我怎么能让它工作呢?
解决方案
您可以为工厂创建一个静态构造函数,并且在此构造函数中可以找到 Dataset 的所有子类(DataSetSeries、DataSetTable、...)。并为它们调用静态构造函数。
public static class Factory
{
static Factory()
{
var datasetDerrivedTypes = Assembly
.GetExecutingAssembly()
.GetTypes()
.Where(t => typeof(DataSet).IsAssignableFrom(t) &&
t != typeof(DataSet));
foreach (var type in datasetDerrivedTypes)
{
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(type.TypeHandle);
}
}
public static void Register(Type type, Func<Series, DataSet> constructorDelegate)
{
}
}
推荐阅读
- ios - gl-react 渲染 IOS 上的旋转照片(仅限 IOS 照片)
- python-3.x - Ansible:Jinja2 无法正确读取字典对象
- javascript - 为什么在设置 Mongoose 连接时在 .then() 中使用 console.log() 时不打印?
- nlp - 聚类后如何测量聚类内句子之间的相似度?
- python - FMU机器学习模型
- javascript - TS RadioGroup 在更改处理程序上返回类型字符串而不是可能的字符串数组
- css - OnePlus移动问题在媒体通话中没有响应
- python - 如何通过套接字从 C# 向 Python 发送图像?
- python - 如何提取由哈希符号包围的列表中的对列表?
- javascript - 如果另一个类的复选框已被选中,如何从 jQuery 过滤器中排除某个复选框类?