c# - 接口方法有接口参数但想在实现中使用类参数
问题描述
我们有一组组件,每个组件都应该以自己的方式加载。
考虑以下:
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 多个组件及其关联的加载器,因此每个组件都具有重载方法的加载器类不是我们想要的
2) 加载器列表是使用 DI 提供给主加载器的,我不完全确定我们将如何使用通用接口来做到这一点。也许是ILoader
启用 DI 的接口,然后ILoader<T>
使用 Load 方法。不知道我将如何从给定映射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
方法中的类型而不是接口
推荐阅读
- javascript - 我无法在 dash_tabulator 中使用 cellClick
- c# - 有没有办法将 .NET 包标记为仅限开发,因此它们不会添加到发布版本中?
- javascript - 访问数组中迭代的元素 ID 的正确语法是什么?
- html5-canvas - 如何使用js强制重绘canvas api?
- windows - 与 Windows 11 兼容的 Flutter 和 Android Studio 版本有哪些?
- spring - MapperScan 运行良好,但想法显示为错误
- url - 如何为 Glassdoor 工资抓取生成正确的链接?
- git - 如何撤消尚未推送的“还原”提交?
- reactjs - 如何从外部 React 组件获取 Auth0 令牌?
- google-cloud-firestore - firebase 中的不安全规则