Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

393
Vistas
HashSet of Guid vs Tuple<Guid, Guid> as Dictionary Key: Order of Guid Shouldn't matter

I need dictionary for which key needs to be two guid order of guid doesn't matter. I have two solutions which are mentioned below, I want to know which one is better and which one should I go if in future I need to add 3rd guid as well as part of key. Performance do matter but if difference is not much then should be fine.

First Solution

 var guids = guids
     .OrderBy(g => g.ToString("N")) // Ordering so key always come as sorted 
     .ToList();

dict[Tuple.Create(guids[0], guids[1]) = "RandomObj";

Second Solution

public class GuidsModel
    {
        public GuidsModel(Guid guid1, Guid guid2)
        {
            Guid1= guid1;
            Guid2= guid2;
        }

        public Guid Guid1 { get; private set; }

        public Guid Guid2 { get; private set; }
    }

 public class GuidsModelComparer : IEqualityComparer<GuidsModel>
    {
        public static GuidsModelComparer Default = new GuidsModelComparer();

        private static IEqualityComparer<HashSet<Guid>> _hashSetComparer = HashSet<Guid>.CreateSetComparer();

        public bool Equals(GuidsModel x, GuidsModel y)
        {
            return _hashSetComparer.Equals(new HashSet<Guid> { x.Guid1, x.Guid2}, new HashSet<Guid> { y.Guid1, y.Guid2});
        }

        public int GetHashCode(GuidsModel obj)
        {
            if (obj == null)
                return 0;

            return _hashSetComparer.GetHashCode(new HashSet<Guid> { obj.Guid1, obj.Guid2});
        }

// usage
var dict = new Dictionary<GuidsModel, object>(GuidsModelComparer.Default);
dict[new GuidsModel(guids[0], guids[1])] = "RandomObj";
over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

It can heavily depend on the context, but I would say that if you want to access the dictionary in more than one place encapsulating the guid "sorting" logic in one place would make more sense. Also personally I would just implement Equals and GetHashcode in the model itself instead of creating custom comparer.

public class GuidsModel
{
    public GuidsModel(Guid guid1, Guid guid2)
    {
        if (guid1.CompareTo(guid2) > 0) // when there will be more than 2 guids can switch to ordering collection i.e. new [] {guid1, guid2, guid3}.OrderBy()...
        {
            Guid1 = guid1;
            Guid2 = guid2;
        }
        else
        {
            Guid1 = guid2;
            Guid2 = guid1;
        }
    }

    public Guid Guid1 { get; private set; }
    public Guid Guid2 { get; private set; }

    private bool Equals(GuidsModel other)
    {
        return Guid1.Equals(other.Guid1) && Guid2.Equals(other.Guid2);
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != this.GetType()) return false;
        return Equals((GuidsModel)obj);
    }

    public override int GetHashCode()
    {
        return HashCode.Combine(Guid1, Guid2);
    }
}

Fiddle

over 4 years ago · Santiago Trujillo Denunciar

0

As far as I understood you need a HashSet<Something> and this something holds two values of same type and the HashSet should also match, if the order is different.

Getting this ignore order is quite complicated. But if you use a factory method to create the instances and this factory method takes care of the ordering, then it gets much simpler:

// Some class that holds two Guids, but it respects ordering
public record GuidPair(Guid First, Guid Second);

public static class Create
{
    public static GuidPair GuidPair(Guid first, Guid second)
    {
        // Order guids somehow in factory method to ensure
        // correct equality comparison
        if (first.CompareTo(second) > 0)
            return new GuidPair(second, first);
        else
            return new GuidPair(first, second);
    }
}

public static class Program
{
    public static void Main(string[] args)
    {
        // Some source for Guid values.
        var values = Enumerable.Range(0, 100)
            .Select(_ => Guid.NewGuid());

        // Create a HashSet with arbitrary values.
        var hashes = values.Zip(values)
            .Select(pair => Create.GuidPair(pair.First, pair.Second))
            .ToHashSet();

        // Pick some "random" element
        var someEntry = hashes.Skip(17).First();
        // Create explicitly a new item with values swapped (with factory method).
        var toCompare = Create.GuidPair(someEntry.Second, someEntry.First);

        // Check if default HashSet comparer works.
        var isAvailable = hashes.Contains(toCompare);

        // Prints "Found { first = Guid, second = Guid }: true"
        Console.WriteLine($"Found {toCompare}: {isAvailable}");

        Console.ReadKey();
    }
}
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda