实现泛型接口的类的字典
本文关键字:字典 实现 泛型接口 | 更新日期: 2023-09-27 18:34:48
我有一个泛型接口,其中包含两个具有严格泛型约束的类型参数,以及针对不同组合的几种实现。
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>
的泛型类型或多或少是不可能的。
有没有更好的解决方案?
您的问题中可能缺少一些明显的东西,因为我不明白问题出在哪里。
首先,我声明一个带有约束的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>;
}
}
就像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();
}
}