Use ExpandoObject instead: I thought it had been deprecated in .NET 1.x - I was mistaken
Conceptualizing this Mess
Dictionary classes, you can get or set value by key, but if you're using them in ASP.NET pages, it can be somewhat clunky:
<%= obj["foo"] %>
What we really want is:
<%= obj.foo %>
Typically, C# will require you to use a strongly typed object instead of a dictionary for this, but that comes with two significant downsides: The first is it means extra coding. The second is you can't add arbitrary fields.
We're going to create a simple "object" that is backed by a dictionary with
string keys. It will solve this problem by also allowing those name/values to be accessed using field accessing syntax.
You already know the upsides, but this approach has downsides as well that come in the form of marginally less performance than a dictionary and lack of compile-time type checking. You should use it when it will increase readability in certain circumstances where you would otherwise use a dictionary.
Coding this Mess
Since you already know how to use it from above, we'll focus on how I made it. The idea here is simple. We derive from
DynamicObject and then implement a dictionary interface on top of it. All that does is override
TrySetMember() and delegate to an inner dictionary. The dictionary members also forward to the inner dictionary. It's all very simple. I won't show all of the code, but I'll show the part that makes the magic of
public override bool TryGetMember(GetMemberBinder binder, out object result)
if (_inner.TryGetValue(binder.Name, out res))
result = res;
result = null;
public override bool TrySetMember(SetMemberBinder binder, object value)
_inner[binder.Name] = (T)value;
T above is the type of values the dictionary holds - the key is always a string.
Using it is simple, and already described above but here's some of the example code - there's more in the included project, including a T4 template for demonstration purposes:
dynamic obj = new DynamicDictionary<object>();
obj.test1 = "foo";
obj["test2"] = "bar";
obj.test3 = 100;
Console.WriteLine("test1 = " + obj.test1);
Console.WriteLine("test2 = " + obj["test2"]);
Console.WriteLine("test3 = " + obj["test3"]);
dynamic keyword, which tells the C# compiler to create a dynamic "call site" where member access is late bound - at runtime instead of compile time. Now you can simply access the object as usual, the exception being there is no Intellisense (autocompletion) in your IDE.
You can construct one of these dynamic objects in your codebehind, and then use them in your ASP.NET pages or T4 templates.
- 13th May, 2020 - Initial submission
Just a shiny lil monster. Casts spells in C++. Mostly harmless.