tag:blogger.com,1999:blog-15136575.post5307403651207664746..comments2023-10-17T12:00:16.772+01:00Comments on Code rant: An Action CacheMike Hadlowhttp://www.blogger.com/profile/16441901713967254504noreply@blogger.comBlogger8125tag:blogger.com,1999:blog-15136575.post-71270932747630701842011-08-20T12:12:35.489+01:002011-08-20T12:12:35.489+01:00Mike,
I completely agree with Rob. What you are r...Mike,<br /><br />I completely agree with Rob. What you are relying on currently is the implementation of getHashCode, which can only be a bad thing.<br /><br />In fact if you look at the documentation for it, it clearly states "Furthermore, the .NET Framework does not guarantee the default implementation of the GetHashCode method, and the value it returns will be the same between different versions of the .NET Framework".<br /><br />This is evident by people who relied on the implementation of string's getHashCode, which has changed across different versions of the CLR.<br /><br />Switch to a dictionary and you will be safe.Richard ODhttps://www.blogger.com/profile/13855706515612188950noreply@blogger.comtag:blogger.com,1999:blog-15136575.post-745889475184773352011-08-10T10:50:32.669+01:002011-08-10T10:50:32.669+01:00Hi Rob,
Thanks for the comment and links. I agree...Hi Rob,<br /><br />Thanks for the comment and links. I agree with everything you say, but I think in this very particular instance what I'm doing is probably OK. Here's my thinking...<br /><br />MethodInfo.GetHashcode is not overriden so it just uses the default Object.GetHashCode(). According to this SO question:<br /><br />http://stackoverflow.com/questions/720177/default-implementation-for-object-gethashcode<br /><br />"The default implementation returns an index for the object determined by the common language runtime. The index is unique to an instance of an object within an AppDomain for an instance of the executing engine."<br /><br />Since the MethodInfo instance will last the lifetime of the application I would expect the hashcode to also be unique for the application's lifetime.Mike Hadlowhttps://www.blogger.com/profile/16441901713967254504noreply@blogger.comtag:blogger.com,1999:blog-15136575.post-42739309460077763072011-08-09T13:56:17.205+01:002011-08-09T13:56:17.205+01:00Thinking that hashcodes are unique is a common mis...Thinking that hashcodes are unique is a common mistake. In reality, there will be two unique MethodInfo instances with the same hashcode (but would still return false for .Equals). I don't agree with your comment to Anonymous, your code is going to behave very oddly if you ever do get a collision. <br /><br />I would go as far as to say that using an object's hashcode as a dictionary key is an antipattern (especially since the Dictionary class (correctly) uses the hashcode anyway)<br /><br />You can fix this by keeping a Dictionary instead.<br /><br />Further reading:<br />http://stackoverflow.com/questions/371328/why-is-it-important-to-override-gethashcode-when-equals-method-is-overriden-in-c<br /><br />http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspxRob Fonseca-Ensorhttp://www.robfe.comnoreply@blogger.comtag:blogger.com,1999:blog-15136575.post-56886520594795074812011-07-20T14:23:13.428+01:002011-07-20T14:23:13.428+01:00What if you add var x = i; and use x instead of i ...What if you add var x = i; and use x instead of i as the argument to the anonymous method?Chrishttps://www.blogger.com/profile/08520368405599361293noreply@blogger.comtag:blogger.com,1999:blog-15136575.post-78336751048770549042011-07-19T14:13:23.275+01:002011-07-19T14:13:23.275+01:00It seems like if you had a collision from GetHashC...It seems like if you had a collision from GetHashCode, you'd end up running the first Action you had cached rather than the new one. <br /><br />Is there some reason that these Actions won't ever have a hash collision?E.Z.https://www.blogger.com/profile/08532288454524803363noreply@blogger.comtag:blogger.com,1999:blog-15136575.post-76814131824097403462011-07-19T09:17:05.700+01:002011-07-19T09:17:05.700+01:00Hi oskark,
Sorry, you right, my example is a bad ...Hi oskark,<br /><br />Sorry, you right, my example is a bad one. Of course the compiler is compiling one example of each lambda, regardless of whether they are called in a loop or not. My cache doesn't add anything as it stands. What I wanted to demonstrate is that other code inside the RunAction can use the action method's hashcode to determine if it's been called with this particular delegate before.<br /><br />Hi Anonymous,<br /><br />Correct, hashcodes are not unique, but they are unique enough for this :)Mike Hadlowhttps://www.blogger.com/profile/16441901713967254504noreply@blogger.comtag:blogger.com,1999:blog-15136575.post-20849106795437993522011-07-18T23:36:50.037+01:002011-07-18T23:36:50.037+01:00Hash codes are not unique of course. You state the...Hash codes are not unique of course. You state the opposite.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-15136575.post-5070776802692328302011-07-18T16:56:37.749+01:002011-07-18T16:56:37.749+01:00Mike,
I don't see the benefit of the cache. T...Mike,<br /><br />I don't see the benefit of the cache. The compiler does that very optimization for you in a for loop. If you comment out the cache logic from the RunAcion method and run it you get the same result.<br /><br />If you want to avoid creating a new object per lambda outside a iteration you could use some more or less elaborate assignment scheme.oskarkhttps://www.blogger.com/profile/04249663512046793009noreply@blogger.com