请告诉我如何在.NET中验证GUID并确保它始终是唯一的?
Guid通常有99.99999999999999999999999999999999%的唯一性。
这取决于您所说的“验证”是什么意思?
用于确定Guid字符串是否确实为Guid的代码如下所示:
private static Regex isGuid =
new Regex(@"^(\{){0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1}$", RegexOptions.Compiled);
internal static bool IsGuid(string candidate, out Guid output)
{
bool isValid = false;
output = Guid.Empty;
if(candidate != null)
{
if (isGuid.IsMatch(candidate))
{
output=new Guid(candidate);
isValid = true;
}
}
return isValid;
}
Guid
可以有其他格式,当前方法将对以下情况抛出异常:"{230a0f8b-81fb-4052-866e-9ac6a7611c77"。 - João AngeloGuid.TryParse()
的引入,这显然比使用正则表达式更可取。不过目前来说,这已经足够且可接受了。 - Wim2^128是一个非常大的数字。它比宇宙寿命内皮秒数量多十亿倍。这个数字太大了,无法验证,答案注定是“42”。使用这些数字的目的在于您不必进行验证。如果您担心出现重复,则您的担忧是错误的原因。机器被流星撞击摧毁的几率要大得多。
小心!
public static bool IsHex(this char c)
{
return ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'));
}
public static bool IsGuid(this string s)
{
// Length of a proper GUID, without any surrounding braces.
const int len_without_braces = 36;
// Delimiter for GUID data parts.
const char delim = '-';
// Delimiter positions.
const int d_0 = 8;
const int d_1 = 13;
const int d_2 = 18;
const int d_3 = 23;
// Before Delimiter positions.
const int bd_0 = 7;
const int bd_1 = 12;
const int bd_2 = 17;
const int bd_3 = 22;
if (s == null)
return false;
if (s.Length != len_without_braces)
return false;
if (s[d_0] != delim ||
s[d_1] != delim ||
s[d_2] != delim ||
s[d_3] != delim)
return false;
for (int i = 0;
i < s.Length;
i = i + (i == bd_0 ||
i == bd_1 ||
i == bd_2 ||
i == bd_3
? 2 : 1))
{
if (!IsHex(s[i])) return false;
}
return true;
}
你无法验证GUID的唯一性。你只能希望它是由一个生成唯一16字节的工具生成的。至于验证,这段简单的代码可能会起作用(假设你正在处理GUID的字符串表示):
bool ValidateGuid(string theGuid)
{
try { Guid aG = new Guid(theGuid); }
catch { return false; }
return true;
}
public static class GuidExtensions
{
public static bool IsGuid(this string value)
{
Guid output;
return Guid.TryParse(value, out output);
}
}
我为此编写了一个扩展程序
public static bool TryParseGuid(this Guid? guidString)
{
if (guidString != null && guidString != Guid.Empty)
{
if (Guid.TryParse(guidString.ToString(), out _))
{
return true;
}
else
return false;
}
return false;
}
TryParseGuid
通常会暗示解析输出作为out参数返回(例如Enum.TryParse
等)。考虑将此扩展方法重命名为IsGuidValid
或类似名称,这将清楚地指示它返回bool
。 - rsobon