工厂根据通用类型C#创建对象

max*_*oin 7 c# generics factory interface

根据传递给Factory类的泛型类型来实例化对象的最有效方法是什么,例如:

public class LoggerFactory
{
    public static ILogger<T> Create<T>()
    {
        // Switch Statement?
        // Generic Dictionary?
        // EX.: if "T" is of type "string": return (ILogger<T>)new StringLogger();
    }
}
Run Code Online (Sandbox Code Playgroud)

你会怎么做?哪个分支声明?等等...

Ken*_* K. 18

我认为最好保持简单,也许是这样的:

public static class LoggerFactory
{
    static readonly Dictionary<Type, Type> loggers = new Dictionary<Type, Type>();

    public static void AddLoggerProvider<T, TLogger>() where TLogger : ILogger<T>, new()
    {
        loggers.Add(typeof(T), typeof(TLogger));
    }

    public static ILogger<T> CreateLogger<T>()
    {
        //implement some error checking here
        Type tLogger = loggers[typeof(T)];

        ILogger<T> logger = (ILogger<T>) Activator.CreateInstance(tLogger);

        return logger;
    }
}
Run Code Online (Sandbox Code Playgroud)

你只需调用AddLoggerProvider你想要支持的每种类型,可以在运行时扩展,它确保你明确地将一个接口的实现添加到库而不是一些对象,因为它不是很快Activator,但创建一个记录器不会无论如何可能是一个瓶颈.希望看起来没问题.

用法:

// initialize somewhere
LoggerFactory.AddLoggerProvider<String, StringLogger>();
LoggerFactory.AddLoggerProvider<Exception, ExceptionLogger>();
// etc..

ILogger<string> stringLogger = LoggerFactory.CreateLogger<string>();
Run Code Online (Sandbox Code Playgroud)

注意:每个都ILogger<T>需要一个无参数构造函数Activator,但是new()在add方法中也确保了通用约束.


Rob*_*ney 6

我想我会这样做:

public class LoggerFactory<T>
{
    private static Dictionary<Type, Func<ILogger<T>>> LoggerMap = 
        new Dictionary<Type, Func<ILogger<T>>>
    {
        { typeof(string), 
            () => new StringILogger() as ILogger<T> },
        { typeof(StringWriter), 
            () => new StringWriterILogger() as ILogger<T> }
    };

    public static ILogger<T> CreateLogger()
    {
        return LoggerMap[typeof(T)]();
    }
}
Run Code Online (Sandbox Code Playgroud)

你支付一些可读性价格(所有那些尖括号,sheesh),但正如你所看到的那样,它只能产生很少的程序逻辑.