c# - 将数据与基本抽象类型的具体子类相关联

标签 c# .net

我最近几次偶然发现需要用一些较低级别的框架类型的东西来做这件事,我想看看是否有更好/更干净的方法来完成这个,即如果我遗漏了什么明显或聪明,就像我发现的时间[ThreadStatic]替换针对线程 ID 的字典查找,以便将数据与线程相关联。

我有一个基础抽象类,我们称它为Entity .每个Entity需要在构造函数中执行一组初始化操作,这取决于被实例化的实际具体类。有没有一种方法可以在不进行字典查找和调用 this.GetType() 的情况下完成此操作? ?

这是一些类似于我现在的代码:

public abstract class Entity
{
    private static Dictionary<Type, Action<EntityData>> _initActions = new Dictionary<Type, Action<EntityData>>();

    private EntityData _data = new EntityData();

    protected Entity()
    {
        _initActions[this.GetType()].Invoke(_data);
    }
}

public class Employee : Entity
{
    public string Name { get; set; }
}

public class Manager : Employee
{
    public List<Employee> Subordinates { get; set; }
}

Employee构造函数和 Manager构造函数需要初始化它们的 _data字段不同,因为它们是不同的类型。 _initActions 集合在任何实例被新建之前通过另一种方法进行初始化,我认为这对本次讨论没有任何意义。

我希望类的使用对于框架的用户来说尽可能简单,所以我不能使用奇怪的技巧,比如要求用户以某种特殊或不直观的方式覆盖每个具体类型中的 Init 方法。

泛型几乎可以工作,因为我可以做类似 Entity<TEntity> 的事情如果我没有任何继承,则获取一个 TEntity 特定的静态字段来存储 init 方法,但需要支持继承,因此无论如何我都需要一个包含 TEntity 子类的所有 init 方法的字典。

此代码在一些非常低级别的数据库引擎类型场景中以 1m 次迭代的紧密循环运行,因此摆脱字典查找确实在某些情况下提供了一些显着的加速(通过替换为 hacky Init 覆盖实现进行测试)。

有什么想法吗?

编辑:

我想说清楚一些事情。实体引擎自动设置 _initAction 来执行初始化其 _data 容器所需的操作。图书馆的“用户”对这个过程一无所知,也不需要。我所询问的只是一种避免字典查找以从基类获取特定于类型的运行时信息的方法,但这可能是不可能的。

是的,这是微优化,但我们已经用真实查询对此进行了测试,并在一些需要实例化大型数据集的查询上减少了 15-20% 的查询时间。

更快的代码如下所示:

public class Employee : Entity
{
    private static EntityInitializer _initMethod = Entity.GetInitMethod(typeof(Employee));

    public string Name { get; set; }

    public Employee()
    {
        _initMethod.Invoke(this);
    }
}

这样,对 Employee 类型进行了一次字典查找。这并不可怕,但它需要 a) 每个类中的样板,我不喜欢,b) 有点容易出错,因为你必须将类型参数与当前类匹配,否则会发生一些奇怪的事情,有点像当你在 WPF 中为依赖属性键入错误的所有者类名称。有点像有时工作,但随后会弹出奇怪的错误并且很难追溯。

归根结底是:考虑到所有这些将附加此数据的类型都实现了一个公共(public)基类,除了使用字典之外,是否还有更好的方法将任意运行时数据附加到类型?

最佳答案

你能不能只创建一个将类型传递给的构造函数?

    protected Entity(Type type)
    {
        _initActions[type].Invoke(_data);
    }
}

public class Employee : Entity
{
    private static Type mytype = typeof(Employee);
    public string Name { get; set; }
    public Employee(): base(mytype)
    { }
}

查找导致性能问题?
字典查找是 0(1) 和几毫秒。
一个程序只能有这么多的类。
实体仍然需要创建对象,创建一个新的 EntityData,并运行 Invoke。
除了初始化实现实体的类。

关于c# - 将数据与基本抽象类型的具体子类相关联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16321287/

相关文章:

c# - 在不调用 Count 的情况下检查 List<T> 是否有任何值?

c# - 将我填充的数组值显示到列表框中并可选择删除它们

c# - 实体类对象改变了它的值,尽管它没有改变

c# - 请求分块加载我的文件的方向(只需要建议)

c# - AutoResetEvent 作为 C# 中的 Lock 替代品?

asp.net - 在 aspnet core 1 应用程序的逻辑层中获取 ClaimsPrincipal

.net - 在 Label 的内容中明确使用 TextBlock 会使 ContentPresenter 行为异常

c# - 这是捕获非特定异常(例如 System.Exception)的坏习惯吗?为什么?

c# - 当我将日期和时间转换为唯一时间时,单元格变为只读

c# - TimeSpan.Parse 错误