首页 > 解决方案 > 为编译时错误关联两个类

问题描述

所以我们有两个抽象类:

1)Entity
2)TaskEntity

并有 impl:

1) EntityA, TaskEntityA;
2) EntityB, TaskEntityB;

我该如何关联:

为此目的:

class BaseTaskHandler<TTask> where TTask:TaskEntity
{
    private readonly IEntityRepo<__Some Magic Here or not here, so I can use__> 
}

换句话说,如果 TTask 是 TaskEntityA 而不是注入(或任何其他获取实例的方式)关联 IEntityRepo<EntityA>

如果我们将使用第二个通用 arg 它可能会导致运行时错误,因为我们可能会犯错误并编写

class BaseTaskHandler<TTask,TEntity>
.
.
.
class ATaskHandler:BaseTaskHandler<TaskEntityA, EntityB>

所以这不是我搜索的答案

标签: c#interfacearchitectureabstraction

解决方案


我想我明白你的问题,所以我会尽我所能回答。

使用您当前的实现,您无法按照您的要求进行操作。如果您希望将类 Entity 与某个类 BaseTaskHandler 中的 TaskHandler 关联起来,那么这意味着所有派生都可以相互关联。这根本不是错误,而是泛型应该如何工作。如果您希望严格将 EntityA 与 TaskEntityA 和 EntityB 与 TaskEntityB 严格关联,则有三种解决方案可以解决您的问题。

你的答案没有错

只要您不将类型 A 与类型 B 配对,您指定的运行时错误可能不是实际错误。如果这确实导致错误并且您不希望这种做法,那么您应该继续到以下两个解决方案...

最简单的解决方案

只需为这两个实体创建两个类。如果您不需要使用泛型并且您没有预见到自己会创建新的实体/任务实体,那么您不需要抽象整个应用程序。只需执行以下操作:

public class EntityHandlerA
{
    private readonly EntityA _entityA;
    private readonly TaskEntityA _taskEntityA;
    public EntityHandlerA(EntityA ea, TaskEntityA tea)
    {
        _entityA = ea;
        _taskEntityA = tea;
    }
}
public class EntityHandlerB
{
    private readonly EntityB _entityB;
    private readonly TaskEntityB _taskEntityB;
    public EntityHandlerA(EntityB eb, TaskEntityB teb)
    {
        _entityB = ea;
        _taskEntityB = teb;
    }
}

通用解决方案

如果您认为实体/任务实体 A 和 B 确实不同,那么您的应用程序中需要另一个抽象级别。因此,如果我们让 A 和 B 从两个不同的基类 BaseEntityA、BaseEntityB 和 BaseTaskEntityA 和 BaseTaskEntityB 继承,则可以在逻辑上将它们分开。

// Highest level
public abstract class Entity { }
public abstract class TaskEntity { } 

// Second level of abstractions for entities of type A and B
public abstract class BaseEntityA : Entity { }
public abstract class BaseEntityB : Entity { }
public abstract class BaseTaskEntityA : TaskEntity { }
public abstract class BaseTaskEntityB : TaskEntity { }

// horizontal association of base entites
public class BaseHandlerA<BaseEntityA, BaseTaskEntityA> { }
public class BaseHandlerB<BaseEntityB, BaseTaskEntityB> { }

// implementation of abstractions
public class EntityA : BaseEntityA { }
public class EntityB : BaseEntityB { }
public class TaskEntityA : BaseTaskEntityA { }
public class TaskEntityA : BasTaskEntityB { }

现在有了这些类,A 类型将不会与您的基本处理程序中的 B 类型相关联。但是,这与之前的解决方案完成的相同,因此仅当您认为必须使用额外的抽象并且 BaseEntityA、BaseEntityB、BaseTaskEntityA 和 BaseTaskEntityB 会有多个派生时才使用它。如果没有进一步的抽象,那么这可能是浪费时间。


推荐阅读