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方法中也确保了通用约束.
我想我会这样做:
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),但正如你所看到的那样,它只能产生很少的程序逻辑.