none
Custom key in dictionary RRS feed

All replies

  • That isn't going to work out for you. In order to be a key the value has to be uniquely identifiable (by calling GetHashCode). Using a ref type like Product means every instance is its own key. At that point you gain nothing by using a dictionary. For example this won't work.

    var product1 = new Product() { ProductName = "A", 
    ProductCategory = "1" };
    
    var product2 = new Product() { ProductName = "B", ProductCategory = 2" };
    
    
    _dictProduct[product1] = 1;
    _dictProduct[product2] = 2;
    
    //Now if you try this
    var product = new Product() { ProductName = "A", ProductCategory = "1" };
    
    //Not found
    var id = _dictProduct[product];
    
    

    Reference types (other than strings and other very specially formatted types) are not really designed to be keys. So in your example of finding a product by name and category, you aren't going to be able to do the constant time lookup that a dictionary provides. The only option you'll have is to enumerate the entire list of keys. A List<Product> would have the same behavior and would work the way you want.

    So, in your example, I'd just use List<Product> in combination with LINQ. If you really need to combine these 2 values into a composite key then create a simple struct (not class) and set them there. Then implement IEquatable<T>, Object.Equals, the C# equality operators, GetHashCode, etc to properly implement equality on the struct. Note that your struct must be immutable because your equality logic has to combine both of them into a hash value and the hash value cannot change for the life of the object. If it does then you won't be able to find it again.


    Michael Taylor http://www.michaeltaylorp3.net

    Thursday, August 23, 2018 9:02 PM
    Moderator
  • See also the constructor of Dictionary that takes an IEqualityComparer. The comparer BoxSameDimension is an example: https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.equalitycomparer-1. To find the value, use dictProduct.TryGetValue. This approach is suitable when you need different kinds of dictionaries that hold Product.

    Probably the simplest solution is to switch to ‘struct Product’. Then you do not need any additional function, since the default ones will work well for your structure.



    Friday, August 24, 2018 5:32 AM