Je suis surpris de ne pas avoir pu trouver de réponse à cela ni dans Google ni ici sur SO, mais quelle est la meilleure façon de comparer un string
à Guid
en tenant compte de la casse, et , le cas échéant, performances
const string sid = "XXXXX-...."; // This comes from a third party library
Guid gid = Guid.NewGuid(); // This comes from the db
if (gid.ToString().ToLower() == sid.ToLower())
if (gid == new Guid(sid))
// Something else?
pdate: Pour rendre cette question plus convaincante, j'ai changé sid
en const
... et puisque vous ne pouvez pas avoir un Guid const
c'est le vrai problème que je traite.
Ne comparez pas Guid
s en tant que chaînes, et ne créez pas de nouveau Guid
à partir d'une chaîne juste pour le comparer à un Guid
existant.
Mis à part les performances, il n’existe pas un seul format standard pour représenter un Guid
sous forme de chaîne, vous courez donc le risque de comparer des formats incompatibles et vous devez ignorer la casse, soit en configurant String.Compare
pour ce faire ou en convertissant chacun en minuscules.
Une manière beaucoup plus idiomatique et performante consiste à créer un Guid
statique et en lecture seule à partir de la valeur de chaîne constante et à toutes les comparaisons utilisant l'égalité Guid native:
const string sid = "3f72497b-188f-4d3a-92a1-c7432cfae62a";
static readonly Guid guid = new Guid(sid);
void Main()
{
Guid gid = Guid.NewGuid(); // As an example, say this comes from the db
Measure(() => (gid.ToString().ToLower() == sid.ToLower()));
// result: 563 ms
Measure(() => (gid == new Guid(sid)));
// result: 629 ms
Measure(() => (gid == guid));
// result: 10 ms
}
// Define other methods and classes here
public void Measure<T>(Func<T> func)
{
Stopwatch sw = new Stopwatch();
sw.Start();
for(int i = 1;i<1000000;i++)
{
T result = func();
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
}
Ainsi, la comparaison de chaînes et la création d'un nouveau Guid
à partir de la valeur constante sont 50 à 60 fois plus chères que la comparaison du Guid
à un Guid
statique et en lecture seule créé à partir de la constante valeur.
Élaboration sur D Stanley
const string sid = "3f72497b-188f-4d3a-92a1-c7432cfae62a";
static readonly Guid guid = new Guid(sid);
static void Main()
{
Guid gid = Guid.NewGuid(); // As an example, say this comes from the db
Measure(() => (gid.ToString().ToLower() == sid.ToLower()));
// result: 177 ms
Measure(() => (gid == new Guid(sid)));
// result: 113 ms
Measure(() => (gid == guid));
// result: 6 ms
Measure(() => (gid == Guid.Parse(sid)));
// result: 114 ms
Measure(() => (gid.Equals(sid)));
// result: 7 ms
}
// Define other methods and classes here
public static void Measure<T>(Func<T> func)
{
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Start();
for (int i = 1; i < 1000000; i++)
{
T result = func();
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
}
Donc, si vous ne pouvez pas stocker votre guid dans une constante, le Guid.Equals () intégré est votre option préférée.