Writing custom indexer for generic dictionary with enumeration as its key - c#

I have a generic dictionary, with an enumeration as its key and an int as its value.
I can't use an indexer on this (error is cannot apply indexer).
How could I write a custom indexer to enable this functionality?
Thanks

Could you do this?
Dictionary<YourEnum, int> dic = new Dictionary<YourEnum, int>();
dic.ElementAt(index);
But If I am not understanding the question can you specify a little more...

Related

Hashtable scrambling?

I have the following hashtable on my application:
System.Collections.Hashtable colunas = new System.Collections.Hashtable();
colunas.Add("Nome", "Nome");
colunas.Add("Departamento", "Departamento");
colunas.Add("Cargo", "Cargo");
After, I pass this hashtable as parameter to a function and when I pass through the hashtable in a foreach I get the following results:
Departamento
Nome
Cargo
Why the result is in that order and not in this:
Nome
Departamento
Cargo
-- EDIT --
Ok, I understood the reason, but what can I use instead of hashtable to preserve the insertion order?
Hashtables do not preserve insertion order.
Instead, they use an unspecified order based on the hashcodes of the keys.
This answer is "promoted" from a comment, by request from the Original Poster.
If it is important for you to keep the order of insertion, you might want to simply use a List<> whose elements are somehow pairs of strings. Two solutions are natural, either:
var colunas = new List<KeyValuePair<string, string>>();
colunas.Add(new KeyValuePair<string, string>("Nome", "Nome"));
colunas.Add(new KeyValuePair<string, string>("Departamento", "Departamento"));
colunas.Add(new KeyValuePair<string, string>("Cargo", "Cargo"));
or:
var colunas = new List<Tuple<string, string>>();
colunas.Add(Tuple.Create("Nome", "Nome"));
colunas.Add(Tuple.Create("Departamento", "Departamento"));
colunas.Add(Tuple.Create("Cargo", "Cargo"));
There's a technical difference between KeyValuePair<,> and Tuple<,> because the former is a struct (value type) and the latter is a class (reference type), but since both KeyValuePair<,> and Tuple<,> are immutable types, that is probably unimportant. Then decide if the property names Key/Value or Item1/Item2 are best suited for your use.
Note that if you use this solution, you don't get the benefits a hashtable offers. You don't get fast lookup on key. And there's no guarantee that the List<> can't have many entries with the same "key" string (first component of the pair). That string could even be null.
If you want to sort the List<> after all, at some point, the call colunas.Sort(); (no comparer argument given) will work for Tuple<,> (lexicographic order) but not for KeyValuePair<,>. Of course if you wanted the collection sorted all the time by keys, you would use SortedDictionary<string, string> as suggested by another answer.
Hashtable represents a collection of key/value pairs that are organized based on the hash code of the key.
but what can I use instead of hashtable to preserve the insertion order?
You have a choice:
System.Collections.Generic.SortedList<TKey, TValue>
System.Collections.Generic.SortedDictionary<TKey, TValue>
See the remarks section here for the differences.

Can't add keyValuePair directly to Dictionary

I wanted to add a KeyValuePair<T,U> to a Dictionary<T, U> and I couldn't. I have to pass the key and the value separately, which must mean the Add method has to create a new KeyValuePair object to insert, which can't be very efficient. I can't believe there isn't an Add(KeyValuePair<T, U>) overload on the Add method. Can anyone suggest a possible reason for this apparent oversight?
You can use the IDictionary<TKey,TValue> interface which provides the Add(KeyValuePair<TKey,TValue>) method:
IDictionary<int, string> dictionary = new Dictionary<int, string>();
dictionary.Add(new KeyValuePair<int,string>(0,"0"));
dictionary.Add(new KeyValuePair<int,string>(1,"1"));
Backup a minute...before going down the road of the oversight, you should establish whether creating a new KeyValuePair is really so inefficient.
First off, the Dictionary class is not internally implemented as a set of key/value pairs, but as a bunch of arrays. That aside, let's assume it was just a set of KeyValuePairs and look at efficiency.
The first thing to notice is that KeyValuePair is a structure. The real implication of that is that it has to be copied from the stack to the heap in order to be passed as a method parameter. When the KeyValuePair is added to the dictionary, it would have to be copied a second time to ensure value type semantics.
In order to pass the Key and Value as parameters, each parameter may be either a value type or a reference type. If they are value types, the performance will be very similar to the KeyValuePair route. If they are reference types, this can actually be a faster implementation since only the address needs to be passed around and very little copying has to be done. In both the best case and worst case, this option is marginally better than the KeyValuePair option due to the increased overhead of the KeyValuePair struct itself.
There is such a method – ICollection<KeyValuePair<K, T>>.Add but as it is explicitly implemented you need to cast your dictionary object to that interface to access it.
((ICollection<KeyValuePair<KeyType, ValueType>>)myDict).Add(myPair);
See
List of Explicit Interface Implementations on Dictionary<K, T>'s documentation page (you'll need to scroll down).
Explicit member implementation
The page on this method includes an example.
Should somebody really want to do this, here is an Extension
public static void Add<T, U>(this IDictionary<T, U> dic, KeyValuePair<T, U> KVP)
{
dic.Add(KVP.Key, KVP.Value);
}
but i would recommend to not do this if there is no real need to do this
Unless I'm mistaken, .NET 4.5 and 4.6 adds the ability to add a KeyValuePair to a Dictionary. (If I'm wrong, just notify me and I'll delete this answer.)
https://msdn.microsoft.com/en-us/library/cc673027%28v=vs.110%29.aspx
From the above link, the relevant piece of information is this code example:
public static void Main()
{
// Create a new dictionary of strings, with string keys, and
// access it through the generic ICollection interface. The
// generic ICollection interface views the dictionary as a
// collection of KeyValuePair objects with the same type
// arguments as the dictionary.
//
ICollection<KeyValuePair<String, String>> openWith =
new Dictionary<String, String>();
// Add some elements to the dictionary. When elements are
// added through the ICollection<T> interface, the keys
// and values must be wrapped in KeyValuePair objects.
//
openWith.Add(new KeyValuePair<String,String>("txt", "notepad.exe"));
openWith.Add(new KeyValuePair<String,String>("bmp", "paint.exe"));
openWith.Add(new KeyValuePair<String,String>("dib", "paint.exe"));
openWith.Add(new KeyValuePair<String,String>("rtf", "wordpad.exe"));
...
}
As can be seen, a new object of type Dictionary is created and called openWith. Then a new KVP object is created and added to openWith using the .Add method.
just because the enumerator for the Dictionary class returns a KeyValuePair, does not mean that is how it is implemented internally.
use IDictionary if you really need to pass KVP's because you've already got them in that format. otherwise use assignment or just use the Add method.
What would be wrong with just adding it into your project as an extension?
namespace System.Collection.Generic
{
public static class DictionaryExtensions
{
public static void AddKeyValuePair<K,V>(this IDictionary<K, V> me, KeyValuePair<K, V> other)
{
me.Add(other.Key, other.Value);
}
}
}
I'm not 100% sure, but I think the internal implementation of a Dictionary is a Hash-table, which means key's are converted to hashes to perform quick look ups.
Have a read here if you want to know more about hashtables
http://en.wikipedia.org/wiki/Hash_table

Array with two classes

Hi im doing a school assignment, and I need to convert this JAVA code to C#
private Map<ItemID, ProductDescription> descriptions = new HashMap()<ItemID, ProductDescription>;
Is it possible to make a straight conversion?
I've already decided to make ItemID into an int, and ProductDescription is a class.
Yes, of course you can.
Please look into following examples:
IDictionary<int, string> h = new Dictionary<int, string>();
h.Add(1, "a");
h.Add(2, "b");
h.Add(3, "c");
SortedList<int, string> s = new SortedList<int, string>();
s.Add(1, "a");
s.Add(2, "b");
I think this is what you are looking for.
You could use a Dictionary<int, ProductDescription> instead.
Dictionary<TKey, TValue> Class
Represents a collection of keys and values. The key must be unique.
private Dictionary<ItemID, ProductDescription> descriptions = new Dictionary<ItemID, ProductDescription>();
The hasmap indeed allows for one null key entry. In the (rare?) case you would need this I'd simply create a special ItemID and use that for the null key.
You could ofcourse make a dictionary descendant with null key support, but that would be overdoing it imho ;-)
Yes, just replace HashMap with Dictionary. You might want to type the variable as an IDictionary (in the same spirit as the Java code), but that's not strictly necessary.
Yes, You can do the conversion using a Dictionary instead of HashMap. And of course it is more effective to get the idea of each code segment and convert. Trying to convert line by line is not recommended since you may miss a better way that can be used to resolve the problem.
There are many options.
There is an
Hashtable in C#
KeyValuePair So it can be List<KeyValuePair<T,U>>
Dictionary //Preferred
This is a good match but,
private IDictionary<ItemID, ProductDescription> descriptions
= new Dictionary<ItemID, ProductDescription>();
Note
HashMap will accept null key values, where as Dictionary will not.
If you really want to support null key values, I'd like to see you reasoning before attempting a perfect .Net HashMap implementation.

Traversing through an arbitrary dictionary tree structure in C#

I am trying to write a recursive C# function that will operate on generic dictionaries of the form IDictionary<string, T> where T is either another IDictionary<string, T> or a string.
My first failed attempt looked something like this:
public string HandleDict(IDictionary<string, string> dict){
// handle the leaf-node here
}
public string HandleDict<T>(IDictionary<string, IDictionary<string, T>> dict){
// loop through children
foreach(string key in dict.Keys){
HandleDict(dict[key]);
}
}
I also tried variants of HandleDict<T>(IDictionary<string, T>) where T : IDictionary<string, T> but that also doesn't quite work. I know that what I want to do could be achieved through a custom class as the parameter instead of dictionaries, and that my attempts are conceptually flawed (there's no end to the recursion in the generic function). I would still like to know if there is actually a way to do what I want here using just generic IDictionaries.
In order to store either a Dictionary<string, string> or a Dictionary<string,??> as a value in a dictionary, you'd need to declare the dictionary to be of type Dictionary<string, object>.
public string HandleDict(IDictionary<string, object> dict)
{
foreach (KeyValuePair<string, object> kvp in dict)
{
Then you'd need to check for each value if it's a string or another Dictionary<string, string> or another Dictionary<string, object> -- C# performs overload resolution at compile-time, not at run-time!
var leaf = kvp.Value as IDictionary<string, string>;
if (leaf != null)
{
HandleDict(leaf);
}
else
{
HandleDict((IDictionary<string, object>)kvp.Value);
}
}
}
Recursion would end when a leaf is reached, because the HandleDict overload for Dictionary<string, string> does not continue the recursion.
However, as you'll note, there's a lot of type checking and casting going on, and a Dictionary<string, object> smells badly -- it essentially defeats the purpose of generics.
I suggest you have a look at the Visitor Pattern instead.
The C# type system is not powerful enough to represent the sort of "higher" generic types that you need to do this in the type system proper. Consider Haskell or F# if you need a language with a richer generic type system.
It is possible to do what you want in C# 4 using the 'dynamic' feature, but I'd recommend against it. Doing that basically starts up the compiler again at runtime. Rather than resorting to runtime type analysis I'd spend some time revisiting the decision to use dictionaries in the first place. I suspect there are better data structures for your actual task at hand. Describe that task and we'll see if there are better data structures.

Difference between Dictionary and Hashtable [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Why Dictionary is preferred over hashtable in C#?
What is the difference between Dictionary and Hashtable. How to decide which one to use?
Simply, Dictionary<TKey,TValue> is a generic type, allowing:
static typing (and compile-time verification)
use without boxing
If you are .NET 2.0 or above, you should prefer Dictionary<TKey,TValue> (and the other generic collections)
A subtle but important difference is that Hashtable supports multiple reader threads with a single writer thread, while Dictionary offers no thread safety. If you need thread safety with a generic dictionary, you must implement your own synchronization or (in .NET 4.0) use ConcurrentDictionary<TKey, TValue>.
Lets give an example that would explain the difference between hashtable and dictionary.
Here is a method that implements hashtable
public void MethodHashTable()
{
Hashtable objHashTable = new Hashtable();
objHashTable.Add(1, 100); // int
objHashTable.Add(2.99, 200); // float
objHashTable.Add('A', 300); // char
objHashTable.Add("4", 400); // string
lblDisplay1.Text = objHashTable[1].ToString();
lblDisplay2.Text = objHashTable[2.99].ToString();
lblDisplay3.Text = objHashTable['A'].ToString();
lblDisplay4.Text = objHashTable["4"].ToString();
// ----------- Not Possible for HashTable ----------
//foreach (KeyValuePair<string, int> pair in objHashTable)
//{
// lblDisplay.Text = pair.Value + " " + lblDisplay.Text;
//}
}
The following is for dictionary
public void MethodDictionary()
{
Dictionary<string, int> dictionary = new Dictionary<string, int>();
dictionary.Add("cat", 2);
dictionary.Add("dog", 1);
dictionary.Add("llama", 0);
dictionary.Add("iguana", -1);
//dictionary.Add(1, -2); // Compilation Error
foreach (KeyValuePair<string, int> pair in dictionary)
{
lblDisplay.Text = pair.Value + " " + lblDisplay.Text;
}
}
There is one more important difference between a HashTable and Dictionary. If you use indexers to get a value out of a HashTable, the HashTable will successfully return null for a non-existent item, whereas the Dictionary will throw an error if you try accessing a item using a indexer which does not exist in the Dictionary
Dictionary is typed (so valuetypes don't need boxing), a Hashtable isn't (so valuetypes need boxing). Hashtable has a nicer way of obtaining a value than dictionary IMHO, because it always knows the value is an object. Though if you're using .NET 3.5, it's easy to write an extension method for dictionary to get similar behavior.
If you need multiple values per key, check out my sourcecode of MultiValueDictionary here:
multimap in .NET
Want to add a difference:
Trying to acess a inexistent key gives runtime error in Dictionary but no problem in hashtable as it returns null instead of error.
e.g.
//No strict type declaration
Hashtable hash = new Hashtable();
hash.Add(1, "One");
hash.Add(2, "Two");
hash.Add(3, "Three");
hash.Add(4, "Four");
hash.Add(5, "Five");
hash.Add(6, "Six");
hash.Add(7, "Seven");
hash.Add(8, "Eight");
hash.Add(9, "Nine");
hash.Add("Ten", 10);// No error as no strict type
for(int i=0;i<=hash.Count;i++)//=>No error for index 0
{
//Can be accessed through indexers
Console.WriteLine(hash[i]);
}
Console.WriteLine(hash["Ten"]);//=> No error in Has Table
here no error for key 0 & also for key "ten"(note: t is small)
//Strict type declaration
Dictionary<int,string> dictionary= new Dictionary<int, string>();
dictionary.Add(1, "One");
dictionary.Add(2, "Two");
dictionary.Add(3, "Three");
dictionary.Add(4, "Four");
dictionary.Add(5, "Five");
dictionary.Add(6, "Six");
dictionary.Add(7, "Seven");
dictionary.Add(8, "Eight");
dictionary.Add(9, "Nine");
//dictionary.Add("Ten", 10);// error as only key, value pair of type int, string can be added
//for i=0, key doesn't exist error
for (int i = 1; i <= dictionary.Count; i++)
{
//Can be accessed through indexers
Console.WriteLine(dictionary[i]);
}
//Error : The given key was not present in the dictionary.
//Console.WriteLine(dictionary[10]);
here error for key 0 & also for key 10 as both are inexistent in dictionary, runtime error, while try to acess.
The Hashtable class is a specific type of dictionary class that uses an integer value (called a hash) to aid in the storage of its keys. The Hashtable class uses the hash to speed up the searching for a specific key in the collection. Every object in .NET derives from the Object class. This class supports the GetHash method, which returns an integer that uniquely identifies the object. The Hashtable class is a very efficient collection in general. The only issue with the Hashtable class is that it requires a bit of overhead, and for small collections (fewer than ten elements) the overhead can impede performance.
There is Some special difference between two which must be considered:
HashTable: is non-generic collection ,the biggest overhead of this
collection is that it does boxing automatically for your values and
in order to get your original value you need to perform unboxing ,
these to decrease your application performance as penalty.
Dictionary: This is generic type of collection where no implicit
boxing, so no need to unboxing you will always get your original
values which you were stored so it will improve your application
performance.
the Second Considerable difference is:
if your were trying to access a value on from hash table on the basis
of key that does not exist it will return null.But in the case of
Dictionary it will give you KeyNotFoundException.
ILookup Interface is used in .net 3.5 with linq.
The HashTable is the base class that is weakly type; the DictionaryBase
abstract class is stronly typed and uses internally a HashTable.
I found a a strange thing about Dictionary, when we add the multiple entries in Dictionary, the order in which the entries are added is maintained. Thus if I apply a foreach on the Dictionary, I will get the records in the same order I have inserted them.
Whereas, this is not true with normal HashTable, as when I add same records in Hashtable the order is not maintained. As far as my knowledge goes, Dictionary is based on Hashtable, if this is true, why my Dictionary maintains the order but HashTable does not?
As to why they behave differently, it's because Generic Dictionary implements a hashtable, but is not based on System.Collections.Hashtable. The Generic Dictionary implementation is based on allocating key-value-pairs from a list. These are then indexed with the hashtable buckets for random access, but when it returns an enumerator, it just walks the list in sequential order - which will be the order of insertion as long as entries are not re-used.
shiv govind
Birlasoft.:)

Categories