我喜欢展示一种已经提出的字典方法的变化。建立在这个解决方案的基础上,你可以这样做:
1. 定义一个基类:
public abstract class JobDoer
{
public abstract void DoJob();
}
定义一个用于职业从业者装饰的属性。
public sealed class JobDoerAttribute : Attribute
{
JobDoerAttribute(string jobDoerId)
{
this.JobDoerId = new Guid(jobDoerId);
}
public Guid JobDoerId { get; private set; }
}
定义具有该属性的实际工作执行类。例如:
[JobDoer("063EE2B2-3759-11DF-B738-49BB56D89593")]
public sealed class SpecificJobDoer : JobDoer
{
public override void DoJob()
{
}
}
定义一个名为
JobDoerFactory
的工厂,使其能够通过其在属性中定义的ID检索
JobDoer
实例。
public static class JobDoerFactory
{
static Dictionary<Guid, JobDoer> cache;
static JobDoerFactory()
{
cache = BuildCache();
}
public static JobDoer GetInstanceById(Guid jobDoerId)
{
return cache[jobDoerId];
}
private static Dictionary<Guid, JobDoer> BuildCache()
{
}
}
在`BuildCache`方法中,您可以通过反射加载`JobDoer`实例。
private static Dictionary<Guid, JobDoer> BuildCache()
{
var jobDoers =
(from assembly in AppDomain.CurrentDomain.GetAssemblies()
from type in assembly.GetTypes()
where type.IsSubclassOf(typeof(JobDoer))
let attributes =
type.GetCustomAttribute(typeof(JobDoerAttribute), true)
where attributes.Length > 0
let attribute = attributes[0] as JobDoerAttribute
select new { attribute.JobDoerId, type }).ToArray();
var cache = new Dictionary<Guid, JobDoer>(jobDoers.Length);
foreach (jobDoer in jobDoers)
{
cache[jobDoer.JobDoerId] =
(JobDoer)Activator.CreateInstance(jobDoer.type);
}
return cache;
}
我没有测试这段代码,所以不知道它是否编译通过,但是我在几年前的一个项目中使用了这种机制。这样可以很容易地定义新的类,而无需将其连接到某个字典。它会在运行时自动完成。
这可能看起来有点过度,但如果你有2000多个JobDoer类,这可能会对你有很大帮助。
更新:
请注意,如果您不喜欢JobDoerAttribute的想法,您也可以将其实现为抽象JobDoer类上的抽象属性。然而,我发现使用属性使代码非常明确和表达。
Action<string, int> action = (s, i) => Console.WriteLine(s.Length > i); action("hello world", 42);
我没有看到任何装箱/拆箱。 - Brian Rasmussen