No Generic Implementation of Ordereddictionary

No generic implementation of OrderedDictionary?

You're right. There's no generic equivalent of OrderedDictionary in the framework itself.

(That's still the case for .NET 4 too, as far as I'm aware.)

Generic implementation of OrderDictionary in C# is showing ambiguous method warnings

I tried to follow what you've done, but it's a spaghetti of nested interfaces.

If you put breakpoints in every GetEnumerator() in OrderedDictionary, you may find it is not calling the enumerator you expect.

The problem, I think, is with trying to implement the non-generic IOrderedDictionary interface along with IDictionary<TKey, TValue>.

If you want generics, why do you need to maintain compatibilty with non-generic IOrderedDictionary?

If you follow (F12) the inheritance trail of IOrderedDictionary, it inherits IDictionary, ICollection, IEnumerable.

Then IDictionary<TKey, TValue> inherits from ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable.

I'm not quite sure what all your requirements are, but I would drop any interfaces you don't need to support. Don't provide code features that you don't need.

This is not completely of your making, but it is the consequence of trying to support multiple interfaces with lots of baggage of their own.

Based on your question, I would only support IDictionary<TKey, TValue> & IList<T>.

And their baggage ;)

For those curious about KeyedCollection, here's an implmentation that does most of what @Mubeen implemented in his code. This is not fully tested, so don't just do a copy->paste if you use this.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Collections.ObjectModel;

namespace TurboLabz.Game
{
public class GenericComparer<TKey> : IComparer<TKey>
{
public static GenericComparer<TKey> CreateComparer(Func<TKey, TKey, int> comparer)
{
return new GenericComparer<TKey>(comparer);
}

internal GenericComparer(Func<TKey, TKey, int> comparer)
{
Comparer = comparer;
}

private Func<TKey, TKey, int> Comparer { get; set; }

public int Compare(TKey x, TKey y)
{
return Comparer(x, y);
}
}

public class OrderedDictionaryKC<TKey, TValue> : KeyedCollection<TKey,KeyValuePair<TKey, TValue>>
{
public OrderedDictionaryKC()
{ }

public OrderedDictionaryKC(IEnumerable<KeyValuePair<TKey, TValue>> collection)
{
if (collection != null)
{
foreach (KeyValuePair<TKey, TValue> item in collection)
{
base.Add(item);
}
}
}

public OrderedDictionaryKC(IDictionary<TKey, TValue> dictionary) : this((IEnumerable<KeyValuePair<TKey, TValue>>)dictionary)
{ }

public ICollection<TKey> Keys
{
get
{
return base.Dictionary.Keys;
}
}

public ICollection<KeyValuePair<TKey, TValue>> Values
{
get
{
return base.Dictionary.Values;
}
}

public void Add(TKey key, TValue value)
{
if (key == null)
{
throw new ArgumentNullException("key");
}

base.Add(new KeyValuePair<TKey, TValue>(key, value));
}

public bool ContainsKey(TKey key)
{
if (key == null)
{
throw new ArgumentNullException("key");
}

return base.Dictionary.ContainsKey(key);
}

public bool TryGetValue(TKey key, out TValue value)
{
KeyValuePair<TKey, TValue> outValue;
var result= base.Dictionary.TryGetValue(key, out outValue);
value = outValue.Value;

return result;
}

protected override TKey GetKeyForItem(KeyValuePair<TKey, TValue> item)
{
return item.Key;
}
}
}

Is there a type-safe ordered dictionary alternative?

Don't use a dictionary if the order of the values are important. The things that come off the top of my head are a SortedDictionary or a List<KeyValuePair>.

OrderedDictionary value not returning list but object

OrderedDictionary isn't a generic class so it works with objects only. You will need to cast or use a different type of collection. For example:

var list = (List<string>) roomList[roomNameTest];

But that might lead to issues if you add something that is not a <List<string> to the dictionary.

Also, I'm not really sure that you need to use OrderedDictionary here, and a strongly typed Dictionary<string, List<string>> would be much better. For example:

var roomList = new Dictionary<string, List<string>>();

//...

if (roomList.ContainsKey(roomNameTest))
{
//...
}

Though I would also recommend using TryGetValue:

if(roomList.TryGetValue(roomNameTest, out var list))
{
foreach (var item in list)
{
Console.WriteLine(item);
}
}

Generic OrderedDictionary: How to get an index of a key?

Try the following code. Note that GenericOrderedDictionary is the Generic OrderedDictionary not the standard .Net as there is no Generic OrderedDictionary.

public static int IndexOfKey<TKey, TValue>(this GenericOrderedDictionary<TKey, TValue> dictionary, TKey key)
{

int index = -1;
foreach (TKey k in dictionary.Keys)
{
index++;
if (k.Equals(key))
return index;
}

return -1;
}

Amended:
If you know both TKey and TValue, you may be able to use the IndexOf() method as well, like below. Assume TKey and TValue are string and int respectively, but of course can be other types.

KeyValuePair<string, int> newItem = new KeyValuePair<string, int>("StringValue", 35);

int keyIndex = GenericOrderedDictionaryObject.IndexOf(newItem );

I thought of this just in case IndexOf() method is well optimized as my first solution is based on a sequential search which is not optimal.

Get value of an OrderedDictionary

I think the problem is that by casting to (object) before retrieving the object from the ordered dictionary, the dictionary tries to locate the key based on Object.Equals(). Object.Equals returns true if the boxed long objects have the same reference (i.e. the ReferenceEquals method returns true). If you don't mind using strings instead of longs as keys, I would recommend to do so.

To see in detail what's going wrong with your code, maybe replace the following line

object objectFound = (IfcElement)ifcList[(object)idElt];

with

object objectKey = (object)idElt;
object objectFound = (IfcElement)ifcList[objectKey];

And then look in the immediate Window of the debugger whether objectKey.ReferenceEquals(x) returns true for any x in

ifcList.Keys

Getting value by name from OrderedDictionary

OrderedDictionary uses objects for both keys and values.

To achieve nesting, just set the value to be another dictionary:

userRoles["UserRoles"] = new Dictionary();

Then you can use:

((Dictionary())userRoles["UserRoles"])["MyKey"] = "My Value";

Analogue of Python's OrderedDict?

I believe System.Collections.Specialized.OrderedDictionary behaves like that.



Related Topics



Leave a reply



Submit