Reputation: 155
Imagine code like the following:
Dictionary<string, MyClass> dictionary = new Dictionary<string, MyClass>() {
{ "Name 1", new MyClass("Name 1", "Second Value 1") },
{ "Name 2", new MyClass("Name 2", "Second Value 2") },
{ "Name 3", new MyClass("Name 3", "Second Value 3") }
}
I need MyClass
to store the key (eg "Name 1") as a field. I'd also like the flexibility of the Dictionary
for what I'm doing (taking advantage of accessing an item by a key).
I can't figure out a way of accomplishing what I want without specifying the key twice like in the code above.
Any ideas on how to solve this?
Upvotes: 0
Views: 304
Reputation: 411
What you want is actually a bidirectional mapping between the objects and their names, therefore under the hood the keys have to be stored twice (in both mapping directions), but you can hide the behavior with:
1) extension methods
public static void Add(this Dictionary<string, MyClass> dictionary, Myclass obj){
dictionary.Add(obj.name, obj);
}
2) Or by deriving a class from Dictionary and write new functions to add and modify stored objects (like the extension method above).
class A : Dictionary<String, MyClass>
{
public void Add(MyClass m)
{
this.Add(m.Name,m);
}
}
*This case it will also work, which is what you really want, I think:
A a = new A() {new MyClass("name", "second value") };
3) Writing implicit conversion operators for myClass to KeyValuePair and vice-versa. In this case you can use MyClass instances like KeyValuePairs with your dictionary (except in initializer list!).
class MyClass
{
// ...other members
public static implicit operator KeyValuePair<string,MyClass>(MyClass obj)
{
return new KeyValuePair<string,MyClass>(obj.Name,obj);
}
public static implicit operator MyClass(KeyValuePair<string,MyClass> kvp)
{
return kvp.Value;
}
}
Feel free to use and combine the methods above.
Upvotes: 1
Reputation: 2742
Another LINQ-esque solution using ToDictionary (avoiding the need for a field):
var dictionary = new[] { "Name 1", "Name 2", "Name 3" }
.ToDictionary(k => k, v => new MyClass(v, "Second Value"));
But this might not be appropriate given you requirements on "Second Value".
EDIT:
Alternative solution if you have naming criteria for the second parameter:
var dictionary = Enumerable.Range(1, 3)
.ToDictionary(k => "Name " + k, v => new MyClass("Name " + v, "Second Value " + v));
Upvotes: 0
Reputation: 26281
You can create all your MyClass
instances in an array and then convert said array into a dictionary using LINQ:
Dictionary<string, MyClass> dictionary = new MyClass[]
{
new MyClass("Name 1", "Second Value 1"),
new MyClass("Name 2", "Second Value 2"),
new MyClass("Name 3", "Second Value 3")
}.ToDictionary(c => c.NameProperty, c => c);
Note that NameProperty
should be the property that holds the dictionary's key (The one that holds these "Name X"
values)
Upvotes: 2