快速查找GUID的方法

时间:2010-03-24 13:49:36

标签: c# .net guid

我有很多(+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;  
....  
}  

6 个答案:

答案 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创建一个词典,并搜索它。