Trouble making a class w/ generics
I'm trying to make a wrapper class around Dictionary and I'm having trouble getting this to compile. I'm getting the error "Type parameter declaration must be an identifier not a type" when I try
Code:
class MultiKeyMap<MyKey, Value>
{
String realKey;
Dictionary<string, Value> hashMap;
public MultiKeyMap()
{
hashMap = new Dictionary<string, Value>();
}
public void Add(List<MyKey> keyList, Value val)
{
realKey = "";
foreach (MyKey elem in keyList)
{
realKey += elem.ToString();
}
hashMap.Add(realKey, val);
}
public bool Get(List<MyKey> keyList, out Value res)
{
realKey = "";
foreach (MyKey elem in keyList)
{
realKey += elem.ToString();
}
return hashMap.TryGetValue(realKey, out res);
}
}
with MyKey being underlined in "class MultiKeyMap<MyKey, Value>". I've tried changing MyKey to several different values, but it's always the same error. Anyone know what I'm doing wrong?
Re: Trouble making a class w/ generics
-.- the error turned out to be that my F keys stopped working. I use the keyboard shortcuts to compile/run. I hit recompile and the error persisted b/c I didn't actually hit recompile since the key wasn't working.
Re: Trouble making a class w/ generics
Oh good. I just compiled the following without error.
Code:
class MultiKeyMap< TK, TV >
{
private readonly Dictionary<string, TV> _hashMap;
public MultiKeyMap()
{
_hashMap = new Dictionary<string, TV>();
}
public void Add( List< TK > keyList, TV value )
{
var realKey = keyList.Aggregate(String.Empty, (current, elem) => current + elem.ToString());
_hashMap.Add( realKey, value );
}
public bool Get( List< TK > keyList, out TV value )
{
var realKey = keyList.Aggregate(String.Empty, (current, elem) => current + elem.ToString());
return _hashMap.TryGetValue(realKey, out value);
}
}
Re: Trouble making a class w/ generics
Quote:
Originally Posted by
homer_3
-.- the error turned out to be that my F keys stopped working. I use the keyboard shortcuts to compile/run. I hit recompile and the error persisted b/c I didn't actually hit recompile since the key wasn't working.
Full of lulz. :-)
Seriously though, a debugging 'tip' you can extract from this experience is that when nothing you seem to be doing is making any difference in the program output, there's a good chance something is wrong with the compilation.
I feel like I've had this problem enough that it's worth nothing...
Re: Trouble making a class w/ generics
One suggestion and one question.
First, when concatenating an unknown number of strings, you should be using a StringBuilder which acts as a string buffer, i.e., it is mutable and you avoid creating n copies when concatenating.
Next, that seems like a really odd interface. Why do you require a list of keys and then just concatenate them together? Seems hard to use and just unintuitive. What if ToString() has not been overriden and returns something like MyNameSpace.MyType? So now you have a key that potentially looks like
MyNameSpace.MyTypeMyNameSpace.MyTypeMyNameSpace.MyTypeMyNameSpace.MyType...
very odd.
Re: Trouble making a class w/ generics
If you have a better suggestion for a way to map 2 keys to 1 value, I'm open to it.
Re: Trouble making a class w/ generics
I do:
Code:
Dictionary<Tuple<T1,T2>, V>
The Tuple class: http://msdn.microsoft.com/en-us/libr...tem.tuple.aspx
Or just make a proper type, but the Tuple should work for you just as well.
Re: Trouble making a class w/ generics
Not sure about C#, but in Java I know that wouldn't work for me. I would need to hold onto the instance of the object I used as a key. The fact that a different tuple instance contained the same values wouldn't matter.
It looks like the base object class in C#, much like Java, has a GetHashCode method. If it is used like Java's, I'd run into the same problem.
Re: Trouble making a class w/ generics
Well, if this were a java forum I might have posted something different ;)
Tuple is a reference type and using the == operator will in fact check reference equality. However, .Equals is overloaded to use value equality (as is how you would/should implement == in comparison to .Equals ). So...
Code:
Tuple<string,string> t1 = new Tuple<string, string>( "Hello", "World" );
Tuple<string,string> t2 = new Tuple<string, string>( "Hello", "World" );
Console.WriteLine( t1 == t2 ); // prints "False"
Console.WriteLine( t1.Equals( t2 ) ); // prints "True"
As anyone versed in .NET should already know, if you want value type equality semantics for reference types (and those semantics make sense for general usage), use .Equals, not ==.
Re: Trouble making a class w/ generics
Quote:
Originally Posted by
homer_3
It looks like the base object class in C#, much like Java, has a GetHashCode method. If it is used like Java's, I'd run into the same problem.
But it has been overridden:
Quote:
Returns the hash code for the current Tuple(Of T1, T2) object. (Overrides Object.GetHashCode.)
src:
MSDN on Touple<T1, T2>
You can always write a small program to test it.
Re: Trouble making a class w/ generics
As Cthulhu pointed out, any type that override .Equals should also override GetHashCode. This is general good practice and will always be done by the .NEt types.
Re: Trouble making a class w/ generics
It's not just good practice, it's *required* if you want to use your type in a Dictionary, or anywhere else where hashing is used as a way to quickly skip files which are definitely not equal.
Re: Trouble making a class w/ generics
well... if you want it to work at least :D
Re: Trouble making a class w/ generics
Quote:
Originally Posted by
BigEd781
This is general good practice [...]
Quote:
Originally Posted by
Mutant_Fruit
It's not just good practice, it's *required* [...]
Well... The fact that it's not enforced (like, by the compiler) but relies on programmer discipline instead makes the line between the two somewhat fuzzy.
Although, IIRC, the compiler does present you with a warning.
Re: Trouble making a class w/ generics
Quote:
Originally Posted by
TheGreatCthulhu
Well... The fact that it's not enforced (like, by the compiler) but relies on programmer discipline instead makes the line between the two somewhat fuzzy.
Although, IIRC, the compiler does present you with a warning.
One word (actually 6 :-)): turn on "treat warnings as errors"
Re: Trouble making a class w/ generics
Yeah, there is a warning for overriding one but not the other.
Re: Trouble making a class w/ generics
Quote:
Originally Posted by
Arjay
One word (actually 6 :-)): turn on "treat warnings as errors"
It still requires self-discipline to turn it on. And then not to turn it off. :)
So, the line is still fuzzy.