在C#中打开Guid的最有效方法

12

在C#中,switch语句仅支持整数类型(不支持Guid),因此简单的O(1)比较表似乎不可能。

匹配Guid的计算最高效的方法是什么?

起初我认为

if(gMyGuid == new Guid("VALUE"))
else if (gMyGuid == new Guid("VALUE2")
else if (gMyGuid == new Guid("VALUE3")
...
else if (gMyGuid == new Guid("VALUEn")

然而通过这样做,每次都会创建一个新的Guid实例进行比较。我可以将Guid转换为字符串,然后在字符串上进行比较,但字符串比较起来相当冗长。

非常感谢您提供的任何建议。


3
要比较字符串表示形式吗? - chiccodoro
2
C#的switch语句不仅支持整型,还支持字符串。但是,它要求在编译时已知需要测试的case标签。 - O. R. Mapper
1
或者您可以定义要比较的GUID,仅在第一次使用时定义并重复使用它们。这样,您就可以依赖实现GUID比较的人来进行优化。 - chiccodoro
2
顺便问一下:这段代码的性能有多重要?你知道,如果你的应用程序包括文件系统访问、网络流量或数据库访问,“微调”这段代码可能会过度杀伤... 那么问题就是“如何使它最易读和可维护”。 - chiccodoro
1
好的,O.R. Mapper的解决方案将使代码更易读和可维护,并且由于它只实例化GUID一次,然后使用GUID的比较实现,因此可能非常高效,根据Gene S引用的链接,这似乎是最快的。 - chiccodoro
显示剩余3条评论
6个回答

18
您可以创建一个 System.Collections.Generic.Dictionary<Guid, ...>,其中...是您需要的有用信息。
在程序启动时,使用所需的guid和值填充字典。
然后,使用字典的TryGetValue方法通过其guid检索值。
我没有为...给出任何文字解释,因为我不知道您想要对guid做什么。也许您想运行某些函数,那么方法指针 (Func<T>或类似的东西) 可能比较适合,否则可以使用提供所需方法的接口类型。这取决于 guid 比较代码的上下文/目的。

4
如果你没有真正需要匹配的值,可以使用HashMap<Guid>代替Dictionary。不过我怀疑你是有需要匹配的值,因为你在if/else链中使用了它。 - Tim S.
函数字典类似于策略模式,使用此方法会导致其自身的问题:https://dev59.com/qEzSa4cB1Zd3GeqPkCYd - oasten

7

使用C#7,您现在可以使用模式匹配来使用switch语句完成此操作。

switch (gMyGuid )
{
    case var g when (g == new Guid("VALUE")):
        break;
    case var g when (g == new Guid("VALUE2")):
        break;
    case var g when (g == new Guid("VALUEN")):
        break;
    default:
        break;
}

这也适用于您定义了静态只读的新Guid("..")变量的情况。

3
创建比较值为静态变量,这样你只需要创建一次。
在你的类顶部添加:
```java public static final String COMPARE_VALUE = "compare value"; ```
private static Guid guidVal1 = new Guid("VALUE");

然后在您的方法中:

if(gMyGuid == guidVal1)
else if .... 

抱歉,这可能是我的样本有问题,我已经更新了问题。不只有一个比较器GUID,而是有很多,所以我需要为每个比较器创建一个新的GUID,这就是我试图避免的问题。 - John Mitchell

2

如果你真的关心性能,使用数字参数的构造函数比Guid(string)构造函数更快。没有字符串参与,也不需要解析任何内容。

以下是其中一个的实现:

public Guid(int a, short b, short c, byte d, byte e, byte f, byte g, byte h, byte i, byte j, byte k)
{
    this._a = a;
    this._b = b;
    this._c = c;
    this._d = d;
    this._e = e;
    this._f = f;
    this._g = g;
    this._h = h;
    this._i = i;
    this._j = j;
    this._k = k;
}

当然,它看起来不太好看,但我认为这是可能最快的构造器。此外,你当然可以将所有比较的Guid存储在一个Dictionary中,并使用其中的值来存储每个处理程序。


1
我会在启动时创建一个Guid的HashSet(T)并进行初始化。
这样,您就不需要写冗长的“if,if,if”语句了。
if (GuidHashSet.Contains(gMyGuid)) {}

如果需要,您可以将新的Guid添加到HashSet中。 HashSet Contains()是O(1)操作。

将它们全部作为Guid(仅一次),因为Guid == Guid使用Guid的内部数据进行比较(equals在Guid.cs中重载)。因此,比较Guid == Guid是最快的。这就是HastSet所做的。


0

OP 似乎一开始就没有两个 GUID。这就是问题所在。 - O. R. Mapper

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接