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.
new object() == new object()false, because reference types have reference equality , 2 instances not same referencenew 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:
by default, reference types'
equals(object obj)method ,==operator callobject.referenceequals(this, obj)under hood.the operators , instance methods need overridden propagate behavior. (e.g. changing
equalsimplementation not affect==implementation, unless nested call added explicitly).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 sourcesiequalitycomparer<t>implementation used:you can provide explicitly in constructor.
it retrieved automatically
equalitycomparer<t>.default(by default). if want configure defaultiequalitycomparer<t>globally accessedequalitycomparer<t>.default, can use undefault (on github).
Comments
Post a Comment