繁体   English   中英

实现通用接口的类的字典

[英]Dictionary of classes that implement a generic interface

我有一个通用接口,带有两个带有严格通用约束的类型参数,以及几种用于不同组合的实现。

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 ,其中的约束由RegisterResolverGetResolver方法强制实施。 对象的实际存储方式无关紧要,因为该存储未在类外部公开。 封装保持一致性:

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();
    }
}

暂无
暂无

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

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