|
I need to implement object in-memory cache .
Each object id can be composed from several string, integer and decimal type values.
ContainsKey does not find existing key in this case.
How to force ContainsKey to compare object contents and find key?
Should i use binaryformatter to serialize CacheKey, overload CacheKey == operator or any other idea ?
To reproduce,
run the code.
Observed:
Key not found
Expected:
Key found
using System.Collections.Generic;<br />
<br />
class test {<br />
struct CacheKey {<br />
object Key;<br />
public CacheKey(object key) {<br />
Key = key;<br />
}<br />
}<br />
<br />
static Dictionary<CacheKey, object> Cache =<br />
new Dictionary<CacheKey, object>();<br />
<br />
static void Main() {<br />
CacheKey key = new CacheKey(new object[] { "test1", 1 });<br />
Cache.Add(key, "");<br />
CacheKey key2 = new CacheKey(new object[] { "test1", 1 });<br />
if (!Cache.ContainsKey(key2))<br />
System.Windows.Forms.MessageBox.Show("Key not found");<br />
else<br />
System.Windows.Forms.MessageBox.Show("Key found");<br />
}<br />
}
Andrus
|
|
|
|
|
To work properly anything you use as a key must impliment GetHashCode().
As far as I know Object[] doesn't impliment it.
Your best bet would probably be to override ToString() on CacheKey to produce a string made up of the supplied components. Then override GetHashCode() to return the GetHashCode() of the composite string.
You'd probably want to impliment the equality stuff too:
Guidelines for Overloading Equals() and Operator == (C# Programming Guide)[^]
|
|
|
|
|
originSH wrote: To work properly anything you use as a key must impliment GetHashCode().
Dictionary class does not use GetHashCode() at all!
Why I need to implement it ?
originSH wrote: Your best bet would probably be to override ToString() on CacheKey to produce a string made up of the supplied components
Can I use binary or xml serializer for this or shoult I create some loop to concatenate values ?
originSH wrote: You'd probably want to impliment the equality stuff too:
If I use string returned from ToString() as key, why to overload equals ?
In this case I can use string as distionary key and I think string comparison works OK .
Andrus
|
|
|
|
|
AndrusM wrote: Dictionary class does not use GetHashCode() at all!
Errm - not true. Anything that ultimately derives from object implements GetHashCode(). What was being suggested though, was that your object needs to override GetHashCode().
|
|
|
|
|
Yes, it implements and .NET memory manager uses it for garbage collection
However, Dictionary object uses linear search.
GetHashCode() can return duplicate codes, it is not possible to use it for searching.
I think that default GetHashCode() implementation is sufficient, no need to waste time overriding it.
Andrus
|
|
|
|
|
The default implementation gives different hash codes for objects that contains the same data. That means that the hash code is based on the reference to the object, not the object itself.
You need to create a hash code based on the data in the object, otherwise the only way to locate the object in the collection is if you already have the reference to it.
---
single minded; short sighted; long gone;
|
|
|
|
|
Thank you.
I'm sorry I do'nt understand this.
Different objects can have same hash codes so has code can used only in hash algoritms which check for object eqality if hash codes match.
Is it simpler to use string as dictionary key and require that object key is string always ?
Will string comparison work by value in this sample ?
Andrus
|
|
|
|
|
AndrusM wrote: Different objects can have same hash codes so has code can used only in hash algoritms which check for object eqality if hash codes match.
Yes, but that is not the problem here. Your problem is that you have two objects that contains the same data, but as the hash code is calculated based on the reference, they will still have different hash codes. As the hash codes are different, it will never compare the objects, as two objects with different hash codes by definition can not be equal.
AndrusM wrote: Is it simpler to use string as dictionary key and require that object key is string always ?
Will string comparison work by value in this sample ?
A string would work. Any type that implements GetHashCode based on the value instead of the reference would work.
---
single minded; short sighted; long gone;
|
|
|
|
|
Any type that implements GetHashCode based on the value instead of the reference would work.
It is sufficient to override GetHashCode() only ?
So I do'nt need to override Equals() method ?
Andrus
|
|
|
|
|
Any class that implements GetHashCode correctly also implements Equals.
---
single minded; short sighted; long gone;
|
|
|
|
|
I'm sorry I do'nt understand this.
Should I override ands re-impement Equals method in CacheKey buy comparing structure contents or not ?
Andrus
|
|
|
|
|
Yes.
---
single minded; short sighted; long gone;
|
|
|
|
|
Hash codes are used for HashTables and Dictionaries, when a key is added the Hash code of the key is used to figure out which bucket the key should be stored in, this is how the searching for the key is speeded up.
http://msdn2.microsoft.com/en-us/library/4yh14awz.aspx[^]
Here is the exact code from the base class libary for when something is inserted into a dictionary:
int num = this.comparer.GetHashCode(key) & 0x7fffffff;
for (int i = this.buckets[num % this.buckets.Length]; i >= 0; i = this.entries[i].next)
AndrusM wrote: In this case I can use string as distionary key and I think string comparison works OK .
Yes, using a string would work very well, but I thought you wanted to use your custom Key class?
|
|
|
|
|
Thank you. Now I understand the need of GetHashKey() override.
However, this seems to be too complicated.
I'nt it simpler to create object key as string manually and use
Dictionary<string, BaseBusinessObject> Cache
instead.
Will string comparison work by value ?
Andrus
|
|
|
|
|
string comparison will work fine
|
|
|
|
|
Hello,
I'm working on a report loader and I'm facing a little problem. I get this error:
The modifier 'public' is not valid for this item.
The code is for making the credentials for viewing the report and is originally from a VB script. I've converted it with a lame online converter but I only get one and the same error at every
This is one of the methods:
<br />
<br />
namespace Reports<br />
{<br />
<br />
public class ReportServerConnection : IReportServerConnection<br />
{<br />
<br />
public bool Microsoft.Reporting.WebForms.IReportServerCredentials.GetFormsCredentials(ref System.Net.Cookie authCookie, ref string userName, ref string password, ref string authority)<br />
{<br />
authCookie = null;<br />
userName = null;<br />
password = null;<br />
authority = null;<br />
<br />
return false;<br />
}<br />
}<br />
}<br />
Anyone an idea? Thanku!
Stef
|
|
|
|
|
When explicitly implimenting an interface method you can't specify an access modifier as its always going to be public.
Remove the public from the method and it'll work fine.
|
|
|
|
|
Thank you that worked out fine
But now i'm getting a second error
<br />
namespace Reports<br />
{ <br />
[Serializable()]<br />
public abstract class ReportServerConnection : IReportServerConnection<br />
{<br />
bool Microsoft.Reporting.WebForms.IReportServerCredentials.GetFormsCredentials(ref System.Net.Cookie authCookie, ref string userName, ref string password, ref string authority)<br />
{<br />
authCookie = null;<br />
userName = null;<br />
password = null;<br />
authority = null;<br />
<br />
return false;<br />
}<br />
}<br />
}<br />
the error is :
'Microsoft.Reporting.WebForms.IReportServerCredentials.GetFormsCredentials' in explicit interface declaration is not a member of interface
and the second is:
<br />
'Reports.ReportServerConnection' does not implement interface member 'Microsoft.Reporting.WebForms.IReportServerCredentials.GetFormsCredentials(out System.Net.Cookie, out string, out string, out string)'<br />
any ideas? Thanku!!
Stef
|
|
|
|
|
If you change out to ref , the signature of the method changes. That means that you are trying to implement an overload of the method that does not exist.
---
single minded; short sighted; long gone;
|
|
|
|
|
hi
how to get the id of row to be updated on th click of button outside the grid view
|
|
|
|
|
One Post is enough. Within 5 minutes of time why are you creating the new thread for the same.
Regards,
Satips.
|
|
|
|
|
Get the ID from database and set the column as 'Hidden'. When clicking the row the ID will passed using script or in codebehind
|
|
|
|
|
Hello,
I`am using VS 2005 Express (C#) . Can someone show me simple code how to view a crystal report in application ?
I have a form FORM1 . Into this form I was add a Crystal Report viewer control 9 .
Then I have a report report.rpt whitch I need to add to view in this application.
Thank you for a help
Ivan
|
|
|
|
|
hi,
how to get the id of the row to be updated when the button is outside the grid view
|
|
|
|
|
If you want to do mass deletes or something like that I usually put a check box column. So I loop through the gridview to see which checkboxes are checked and then I know which rows to delete or whatever you are trying to do.
Hope that helps.
Ben
|
|
|
|