Reputation: 7829
Suspect my brain isn't working today - I need to extract a list of keys, etc:
Dictionary<string, MyClass> myDict;
List<String> myKeys = myDict.Keys;
The second line fails to compile as the Keys property returns a "KeyCollection" class and not a list<> of key objects.
Upvotes: 27
Views: 41225
Reputation: 1
I've been created a simplified Dictionary:
using System;
using System.Collections;
using System.Collections.Generic;
namespace CS_Library
{
public sealed class Dict : IEquatable<Dict>, IDict
{
private ArrayList keys, values;
private int LocalCount; public int Count { get => LocalCount; }
public Dict()
{
keys = new ArrayList();
values = new ArrayList();
}
public Dict(ArrayList keys, ArrayList values)
{
this.keys = keys;
this.values = values;
}
~Dict() { }
public object this[object key] { get => values[keys.IndexOf(key)]; }
public int Add(object key, object value) // The more strange is the Visual Studio don't color the 'value'
{
if (keys.IndexOf(key) > -1 || values.IndexOf(value) > -1)
{
return -1;
}
LocalCount = keys.Add(key);
return values.Add(value);
}
public void Override(object newKey, object newValue, object key)
{
if (keys.IndexOf(newKey) > -1 || values.IndexOf(newValue) > -1)
{
return;
}
keys[keys.IndexOf(key)] = newKey;
values[keys.IndexOf(key)] = newValue;
}
public void Delete(object key)
{
if (keys.IndexOf(key) == -1)
{
return;
}
values.RemoveAt(keys.IndexOf(key));
keys.Remove(key);
}
public void DeleteAt(int index)
{
if (index < 0 || index > keys.Count)
{
return;
}
keys.RemoveAt(index);
values.RemoveAt(index);
}
public void Erase()
{
values = null;
keys = null;
}
public void Rebuild(ArrayList newKeys, ArrayList newValues)
{
if (keys != null && values != null)
{
throw new InvalidOperationException("Expected 'Erase()' method before this one. Or the 'Queue_Rebuild()' method instead this one.");
}
keys = newKeys;
values = newValues;
}
public void Queue_Rebuild(ArrayList newKeys, ArrayList newValues)
{
Erase();
Rebuild(newKeys, newValues);
}
public override bool Equals(object obj)
{
return Equals(obj as Dict);
}
public bool Equals(Dict other)
{
return other != null &&
EqualityComparer<ArrayList>.Default.Equals(keys, other.keys) &&
EqualityComparer<ArrayList>.Default.Equals(values, other.values) &&
LocalCount == other.LocalCount;
}
public override int GetHashCode()
{
return HashCode.Combine(keys, values, LocalCount);
}
public override string ToString()
{
string r = "{ ";
bool first = true;
for (int i = 0; i < LocalCount; i++)
{
if (!first)
{
r += ", ";
}
else
{
first = false;
}
r += $"{keys[i]}:{values[i]}";
}
return r + " }";
}
public static bool operator ==(Dict left, Dict right)
{
return EqualityComparer<Dict>.Default.Equals(left, right);
}
public static bool operator !=(Dict left, Dict right)
{
return !(left == right);
}
public static Dict operator +(Dict left, Dict right)
{
Dict r = left;
for (int i = 0; i < right.Count; i++)
{
r.Add(right.keys[i], right.values[i]);
}
return r;
}
}
}
It's not finished, so you can do any changes.
Upvotes: 0
Reputation: 1015
Yes, you can try - IEnumerable<String> myKeys = myDict.Keys;
Always a good idea to use IEnumerable
(a more generic type).
Upvotes: 8
Reputation: 9563
KeyCollection implements the IEnumerable
interface.
You can use an extension method to convert it to a list.
List<String> myKeys = myDict.Keys.ToList();
Or use a different constructor:
List<String> myKeys = new List<String>(myDict.Keys);
Upvotes: 26
Reputation: 9016
If you need a true list:
List<string> myKeys = new List<string>(myDict.Keys);
Upvotes: 4
Reputation: 82375
Using LINQ you can do the following...
List<String> myKeys = myDict.Keys.ToList();
However depending on what your goal is with the keys (selective enumeration etc) it might make more sense to work with the key collection and not convert to a list.
Upvotes: 41