我有一个通用接口,带有两个具有严格通用约束的类型参数,以及几种不同组合的实现。
public interface IResolver<TIn, TOut> where ... {...}
我想创建一个(静态)解析器工厂,它将存储已知实现的实例,并按照以下方式提供它们:
public static ResolverFactory{
public static IResover<TIn, TOut> GetResolver<TIn, TOut> where ... ()
{
//access some storage dictionary to return the correctly typed instance
}
}
如何创建这样一个包含IResover<Entity1, Entity2>
和IResolver<Entity3, Entity4>
的内容?
我能想到的一个选择是使用单独的非通用“标记”界面,如:
public interface IResolver {}
public interface IResolver<TIn, TOut> : IResolver where ....
{...}
并使用
Dictionary<Type, Dictionary <Type, IResolver>> storage;
public RegisterResolver(IResolver resolver)
{
//add to storage - how?
}
但是这种情况基本上使通用参数的约束无效。
此外,在添加IResolver
时,获取IResolver<TIn, TOut>
的泛型类型或多或少是不可能的。
有更好的解决方案吗?
答案 0 :(得分:3)
在你的问题中可能有一些显而易见的东西,因为我不明白问题出在哪里。
首先,我声明一个带有约束的IResolver<TIn, TOut>
接口:
public interface IResolver<TIn, TOut>
where TIn : Stream
{
}
然后,我创建了一个ResolverFactory
,其中约束由RegisterResolver
和GetResolver
方法强制执行。实际存储对象的方式并不重要,因为存储不会暴露在类之外。封装保持一致性:
public static class ResolverFactory
{
private static Dictionary<Type, object> storage = new Dictionary<Type, object>();
public static void RegisterResolver<TIn, TOut>(IResolver<TIn, TOut> resolver) where TIn : Stream
{
storage[typeof(IResolver<TIn, TOut>)] = resolver;
}
public static IResolver<TIn, TOut> GetResolver<TIn, TOut>() where TIn : Stream
{
return storage[typeof(IResolver<TIn, TOut>)] as IResolver<TIn, TOut>;
}
}
答案 1 :(得分:2)
像KooKiz的答案一样,但没有演员,也没有字典。用法类似。
//Rather than:
var res = ResolverFactory.GetResolver<Stream, Hat>();
//You Do:
var res = ResolverFactory<Stream, Hat>.GetResolver();
只需移动通用参数,还可以在更少的位置定义通用约束。
public interface IResolver<TIn, TOut>
where TIn : Stream
{
}
//Still static, but now there is one per TIn,TOut pair
//so no need for dictionary, so also no need for casting.
public static class ResolverFactory<TIn, TOut> where TIn : Stream
{
private static IResolver<TIn, TOut> _resolver;
public static void RegisterResolver(IResolver<TIn, TOut> resolver)
{
_resolver = resolver;
}
public static IResolver<TIn, TOut> GetResolver()
{
return _resolver;
}
}
internal class Program
{
private static void Main(string[] args)
{
ResolverFactory<Stream, Hat>.RegisterResolver(new MyStreamToHatResolver());
var res = ResolverFactory<Stream, Hat>.GetResolver();
}
}