c# - Using a class versus struct as a dictionary key -


suppose had following class , structure definition, , used them each key in dictionary object:

public class myclass { } public struct mystruct { }  public dictionary<myclass, string> classdictionary; public dictionary<mystruct, string> structdictionary;  classdictionary = new dictionary<myclass, string>(); structdictionary = new dictionary<mystruct, string>(); 

why works:

myclass classa = new myclass(); myclass classb = new myclass(); this.classdictionary.add(classa, "test"); this.classdictionary.add(classb, "test"); 

but crashes on runtime:

mystruct structa = new mystruct(); mystruct structb = new mystruct(); this.structdictionary.add(structa, "test"); this.structdictionary.add(structb, "test"); 

it says key exists, expected, struct. class treats 2 separate entries. think has data being held reference versus value, more detailed explanation why.

  1. new object() == new object() false, because reference types have reference equality , 2 instances not same reference

  2. new int() == new int() true, because value types have value equality , value of 2 default integers same value. note, if have reference types or default values incremental in struct, defaults may not compare equal structs either.

you can override equals , gethashcode methods , equality operators of both structs , classes if don't default equality behavior.

also, if want safe way set dictionary value, regardless, can dictionary[key] = value; add new values or update old ones same key.

update

@280z28 posted a comment pointed out how answer misleading, recognize , want address. it's important know that:

  1. by default, reference types' equals(object obj) method , == operator call object.referenceequals(this, obj) under hood.

  2. the operators , instance methods need overridden propagate behavior. (e.g. changing equals implementation not affect == implementation, unless nested call added explicitly).

  3. all default .net generic collections use iequalitycomparer<t> implementation determine equality (not instance method). iequalitycomparer<t> may (and does) call instance method in implementation, not can count on. there 2 possible sources iequalitycomparer<t> implementation used:

    1. you can provide explicitly in constructor.

    2. it retrieved automatically equalitycomparer<t>.default (by default). if want configure default iequalitycomparer<t> globally accessed equalitycomparer<t>.default, can use undefault (on github).


Comments

Popular posts from this blog

linux - xterm copying to CLIPBOARD using copy-selection causes automatic updating of CLIPBOARD upon mouse selection -

c++ - qgraphicsview horizontal scrolling always has a vertical delta -