我有很多(+2000)GUID(在某些网络类中),我的程序在收到消息并完成与之相关的工作时必须找到其中一个。 积极的一点是我有一个硬编码生成器,但最快的方法是我的目标(我不知道如何实现它)。
我的代码应该做这样的事情:
switch(received guid)
{
case guid1: do job 1; break;
case guid2: do job 2; break;
case guid3: do job 3; break;
case guid4: do job 4; break;
....
}
答案 0 :(得分:15)
您可以使用Guid作为键创建一个Dictionary,并将委托引用作为值。这将确保快速查找。
答案 1 :(得分:9)
创建一个用于执行Job的接口,然后实现2000个完成工作的类,每个类都知道自己的guid。然后使用guid作为键将类添加到字典中。然后当你获得guid时,你在字典中查找对象并在界面上调用方法。
public interface IJobDoer
{
void DoJob();
Guid Guid{get;}
}
public class FirstJobType : IJobDoer
{
void DoJob()
{
/// whatever...
}
Guid Guid { get{return "insert-guid-here";}}
}
答案 2 :(得分:6)
使用哈希表将Guid映射到委托或代表任务的类,例如Dictionary<Guid, Action>
或Dictionary<Guid, Task>
。
答案 3 :(得分:4)
Dictionary<Guid, JobDelegate>
可能比switch语句更快。
但你必须要确定一下。
答案 4 :(得分:3)
我喜欢展示其他人已提出的词典方法的变体。在此解决方案的基础上,您可以执行以下操作。
1定义基类:
public abstract class JobDoer
{
public abstract void DoJob();
}
2定义工作实践装饰的属性。
public sealed class JobDoerAttribute : Attribute
{
JobDoerAttribute(string jobDoerId)
{
this.JobDoerId = new Guid(jobDoerId);
}
public Guid JobDoerId { get; private set; }
}
3定义使用该属性修饰的实际作业实践者类。例如:
[JobDoer("063EE2B2-3759-11DF-B738-49BB56D89593")]
public sealed class SpecificJobDoer : JobDoer
{
public override void DoJob()
{
// Do a specific job
}
}
4定义一个JobDoerFactory
,允许按照属性中定义的ID检索JobDoer
个实例:
public static class JobDoerFactory
{
static Dictionary<Guid, JobDoer> cache;
static JobDoerFactory()
{
// Building the cache is slow, but it will only run once
// during the lifetime of the AppDomain.
cache = BuildCache();
}
public static JobDoer GetInstanceById(Guid jobDoerId)
{
// Retrieving a JobDoer is as fast as using a switch statement.
return cache[jobDoerId];
}
private static Dictionary<Guid, JobDoer> BuildCache()
{
// See implementation below.
}
}
在BuildCache
方法中,您可以使用反射来加载JobDoer
个实例。
private static Dictionary<Guid, JobDoer> BuildCache()
{
// This is a bit naive implementation; we miss some error checking,
// but you'll get the idea :-)
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)
{
// Note that actually a single instance of the job doer is
// cached by ID. This means that every Job Doer must be
// thread-safe and usable multiple times. If this is not
// feasable, you can also create store a set of Func<JobDoer>
// objects that enable creating a new instance on each call.
cache[jobDoer.JobDoerId] =
(JobDoer)Activator.CreateInstance(jobDoer.type);
}
return cache;
}
我没有测试这段代码,所以我不知道它是否编译,但几年前我在一个项目中使用了这个机制。通过这种方式,可以轻松定义新类,而无需将其连接到某些字典。它在运行时自动完成。
这看起来有点像矫枉过正,但是如果你有+2000 JobDoer
个课程,这可能会对你有所帮助。
更新:
请注意,如果您不喜欢JobDoerAttribute
的想法,您还可以在抽象JobDoer
类上将其实现为抽象属性。但是,我发现使用一个属性可以使代码非常明确和富有表现力。
答案 5 :(得分:0)
使用Guid和Action创建一个词典,并搜索它。