I'm going nuts here. It's probably because I've missed some rule, but if so, then please tell me.
I'm trying to create a Dictionary
with a string for key and an anonymous object as value. Or, actually I'm not just trying, I'm doing it.
But when I want to alter a specific parameter in the object, it goes wrong.
I declare the dictionary like this:
var areas = new Dictionary<string, object>
{
{"Key1", new {name = "Name1", today = 0, all = 0}},
{"Key2", new {name = "Name2", today = 0, all = 0}},
...
}
And then I'm assuming I can do this:
foreach (var area in areas.Keys.ToArray())
{
var areaname = areas[area].name;
}
but Visual Studio does not agree, and refuses to compile. If I write this, though, everything works as I would think - but that doesn't really help me out, it's just making me more frustrated.
var areaname = new
{
name = "Nametest", today = 0, all = 0
};
var testname = areaname.name;
What am I doing wrong? Why isn't it working for me? Is it simply impossible to do so?
Thanks for all your answers, they surely cleared things up a bit! I think I might have been confusing the type object with the idea of objects, that is classes, in C# out of frustration. I'll rethink the whole design business and probably do something completely different instead of using evil or dirty solutions. Though interesting, I don't think my relationship with C# has evolved that far yet!
A dictionary value can be any object (even the dictionary itself!
You can create the Dictionary<TKey, TValue> object by passing the type of keys and values it can store. The following example shows how to create a dictionary and add key-value pairs. In the above example, numberNames is a Dictionary<int, string> type dictionary, so it can store int keys and string values.
The dictionary stores objects as key-value pairs and can be used to represent complex real-world data.
A Python dictionary is a collection of key-value pairs where each key is associated with a value. A value in the key-value pair can be a number, a string, a list, a tuple, or even another dictionary. In fact, you can use a value of any valid type in Python as the value in the key-value pair.
This will not work because you have declared the dictionary as Dictionary<string, object>
.
You could instead try Dictionary<string, dynamic>
.
This will not work because you have declared the dictionary as Dictionary<string, object>
.
C# creates a new type in the background for you (which you can't access) that has these properties (herewith known as an anonymous type). The only time you can use it directly is when it is still var
type - as soon as you add it to that dictionary it is cast to object
and thus you can't access the properties any more.
Option 1
You could instead try Dictionary<string, dynamic>
. Dynamic will be able to access these properties - but this is only supported in C#/.Net 4.0
Option 2
You can get the type back using a technique known as demonstration (cast by example). This isn't a documented feature, is wasteful and is somewhat a hack. This is a horrible evil trick - especially because it won't work across assemblies.
public static T Demonstrate<T>(this T demonstration, object value)
{
return (T)value;
}
You can then access the original properties like so:
var area = new { name = "", today = 0, all = 0 }.Demonstrate(areas[name]);
var areaName = value.name;
Option 3 This is honestly the best way
Write a class. If you like the fact that the C# compiler does all of the Equals
, GetHashCode
and ToString
work for you, you can just use something like ILSpy to grab the original code. Thus:
class AreaInfo
{
public string Name { get; set; }
public int Total { get; set; }
public int All { get; set; }
public override bool Equals(object obj)
{
var ai = obj as AreaInfo;
if (object.ReferenceEquals(ai, null))
return false;
return Name == ai.Name && Total == ai.Total && All == ai.All;
}
public override int GetHashCode()
{
var hc = 0;
if (Name != null)
hc = Name.GetHashCode();
hc = unchecked((hc * 7) ^ Total);
hc = unchecked((hc * 21) ^ All);
return hc;
}
public override string ToString()
{
return string.Format("{{ Name = {0}, Total = {1}, All = {2} }}", Name, Total, All);
}
}
Correct your dictionary:
var areas = new Dictionary<string, AreaInfo>
{
{"Key1", new AreaInfo() {Name = "Name1", Today = 0, All = 0}},
{"Key2", new AreaInfo() {Name = "Name2", Today = 0, All = 0}},
...
};
And now things will work the way you expect them to.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With