繁体   English   中英

接口方法有接口参数但想在实现中使用 class 参数

[英]Interface method has interface argument but want to use class argument in the implementation

我们有一组组件,每个组件都应该以自己的方式加载。

考虑以下:

public interface IComponent
{
    Type LoaderType {get;}
}

public class ComponentA: IComponent
{
    Type LoaderType => typeof(ComponentALoader);
}

public class ComponentB: IComponent
{
    Type LoaderType => typeof(ComponentBLoader);
}

public interface ILoader
{
    void Load(IComponent example);
}

有没有办法让我在实现ILoader时可以在加载器中使用组件类型而不是接口(以避免强制转换)?

例子:

public class ComponentALoader: ILoader
{
    void Load(ComponentA component) {}
}

public class ComponentBLoader: ILoader
{
    void Load(ComponentB component) {}
}

[编辑:这是当前有效的实现,但需要在每个加载器中进行强制转换]:

public class ComponentALoader: ILoader
{
    void Load(IComponent component) 
    {
        // This is the cast that I was looking to avoid in favor of having the type in the method signature
        var compA = (ComponentA) component;
        doSomethingWithA();
    }
}

public class ComponentBLoader: ILoader
{
    void Load(IComponent component)
    {
        // This is the cast that I was looking to avoid in favor of having the type in the method signature
        var compB = (ComponentB) component;
        doSomethingWithB();
    }
}

public class ComponentBLoader: ILoader
{
    void Load(ComponentB component) {}
}

入口点类似于:

List<IComponent> components = listOfComponents;
foreach (var component in components)
{
    // Retrieves the correct loader from a list of loaders 
    // based on the type property on the components
    var loader = getLoaderForComponent(component); 
    loader.Load(component);
}

编辑: 1) 值得注意的是,我们在这里很容易谈论 100 多个组件及其相关的加载器,因此对于每个组件具有重载方法的加载器 class 并不是我们想要的 go

2) 加载器列表是使用 DI 提供给主加载器的,我不完全确定我们将如何使用通用接口来做到这一点。 可能是启用 DI 的ILoader接口,然后ILoader<T>与 Load 方法。 不知道如何从给定的 ILoader 调用ILoader来调用ILoader<T>上的方法。

3) tl;dr 我们希望避免主加载器知道许多类型的组件和加载器

4)当前的解决方案有效,也许在每个装载机中进行强制转换是必要的

让我们看看我对你的问题的理解程度。 正如评论中所说,为了避免强制转换,您可以使您的接口通用并在实现类中定义通用类型:

public interface IComponent
{
    Type LoaderType { get; }
}

public class ComponentA : IComponent
{
    public Type LoaderType => typeof(ComponentALoader);
}

public class ComponentB : IComponent
{
    public Type LoaderType => typeof(ComponentBLoader);
}

public interface ILoader<T> where T : IComponent // This restriction allows only types that implement the interface inside the load method
{
    void Load(T example);
}

public class ComponentALoader : ILoader<ComponentA>
{
    public void Load(ComponentA component) { }  
}

public class ComponentBLoader : ILoader<ComponentB>
{
    public void Load(ComponentB component) { }
}

此代码编译,您可以使用Load方法中的类型而不是接口

您必须使用通用 class

public class Component<T> wher T:IComponent
{
    void Load(T component) {}
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM