Hugoware

The product of a web developer with a little too much caffeine

Posts Tagged ‘Dynamic

Almost Sorta Real Dynamic in .NET

with 8 comments

This post discusses the basics of writing your own dynamic type – If you’re interested in the finished code make sure to download the source.

The new dynamic keyword is a great way to create and modify a dynamic object in your .NET code – For example, check out this bit of code.

dynamic counter = new {
    sent = 0,
    received = 0
};
counter.sent++;

… Oh… wait… That doesn’t actually work…

That’s because even though you have an object declared as dynamic, it is still just the same old object it always was under the hood. Maybe not the dynamic utopia we were expecting. Seems like plain ol’ Reflection with a slightly cleaner syntax.

Bummer…

However, Microsoft was awesome enough to actually allow us to create our own dynamic types by simply inheriting from the DynamicObject class. This post looks at how we can create a semi-dynamic object by handling the binding methods ourselves.

[Source Code: Dynamic.cs]

Our goal is to create an object that we can add, remove and change values on the fly. It ends up being a little easier than we expect. Let’s look at the minimum code we are going to need to get started.

public class SimpleDynamic : DynamicObject {

    //contains the values to use
    private Dictionary<string, object> _Values = new Dictionary<string, object>();

    //handles getting values from our object
    public override void TryGetMember(GetMemberBinder binder, out object result) {
        //...
    }

    //handles assigning values to our object
    public override bool TrySetMember(SetMemberBinder binder, object value) {
        //...
    }

}

Note: If you downloaded the source code above you might be wondering why these examples don’t look the same. The source code is the complete Dynamic class while this post only goes over the basics of using the DynamicObject class.

In order to create our dynamic object we must handle getting and setting values. We can use a simple Dictionary<string,object> to hold our values until we need them.

//handles getting values from our object
public override void TryGetMember(GetMemberBinder binder, out object result) {
    return this._Values.TryGetValue(binder.name, out result);
}

//handles assigning values to our object
public override bool TrySetMember(SetMemberBinder binder, object value) {
    this._Values.Remove(binder.name);
    if (value is object) { this._Values.Add(binder.name, value); }
    return true;
}

Not much code, but now our dynamic object is a little more dynamic than it was before. We can now work with properties a lot easier.

//create the new object
dynamic simple = new SimpleDynamic();

//add and update some values
simple.red = "#f00";
simple.green = "#0f0";
simple.count = 10;
simple.add = new Action<int>(value => simple.count += value);

//and check the values
Console.WriteLine(simple.red); // #f00
Console.WriteLine(simple.green); // #0f0
Console.WriteLine(simple.count); // 10

//invoke methods
simple.add(5);
Console.WriteLine(simple.count); // 15

Of course this class isn’t that helpful since it’s only regular Dictionary without string indexes but it is interesting to see how you can make a ‘dynamic’ object with only a few lines of code.

As for the included source code, it has a few extra features that this class doesn’t have.

  • Use Anonymous Types directly to build out entire objects.
  • Support for the += operator.
  • Enumeration through member names.
  • String indexes (for both single and nested properties).

Here are a few examples the Dynamic.cs class can do.

//create using anonymous types (and nested anonymous types)
dynamic info = new Dynamic(new {
    name = "Hugo",
    age = 30,
    settings = new {
        color = "orange",
        homepage = "website.com"
    }});

//add values using +=
info.create = new { value = false; }
info.nested.value.allowed = 55;

//enumeration of properties
foreach(string prop in info) {
    Console.WriteLine("{0}: {1}", prop, info[prop]);
}

I’d caution against using this a lot in your projects, but it is really interesting to see the kind of control Microsoft has built into the new DynamicObject class.

[Source Code: Dynamic.cs]

Advertisements

Written by hugoware

July 15, 2010 at 12:32 am

Simplify Using Anonymous Types

with 7 comments

New Version Available:Check out this post about the AnonymousType class Remixed!.

When you’re using ASP.NET MVC you pass information from the Controller to the View. Your information is found in the ViewDataDictionary where you can cast the info back into whatever form it originally was. Additionally, you can even specify a model type for the page so that no casting is required to access your information.

It may be a little inconvenient, but it’s not bad. This just means you need to either define the class in advance or limit yourself to simple values.

If you’re writing LINQ queries and creating anonymous types then you’re in a tougher situation. I’ve seen people try and come up with solutions for accessing an anonymous type after its been created, but nothing seemed all that intuitive.

In the next version of C# we’re going to see the new dynamic declaration which will most likely solve this problem. For now, Reflection is about the only way you solve this issue.

On a recent project I got a little tired of trying to manually do this each time. I ended up writing a wrapper class (included at the end of the post). The example below shows how you can use this class AnonymousType.

//Controller
//==================
this.ViewData["details"] = new {
  name = "Jim",
  age = 30
};


//View
//==================
AnonymousType details = new AnonymousType(this.ViewData["details"]);

//access properties
string name = details.Get<string>("name");
int age = details.Get<int>("age");

//supply a default type in case the property doesn't exist
bool fake = details.Get<bool>("someFakeProperty", false);

//Use the properties by name - maps to the argument name
details.Use((string name, int age) => { 
  Console.WriteLine("{0} is {1} years old", name, age);
});

//An wrong property name (wrong type or incorrect case) will cause an error
details.Use((int NAME) => { /* Error! */ });

It’s really just Reflection, but it streamlines using unknown types inside of a View.

Now, if you are thinking “What about methods? or Fields?” then you’re like me. Now, if your second thought was “Well wait, if it has methods then it’s a defined class, we should just cast it instead.”, then you’re much smarter than me. Unfortunately, I spent an hour or so writing ComplexAnonymousType that would call methods (even match correct signatures), access fields, the works… then to realize how much of a wasted effort it was. 🙂

Anyways, try it out if interested. Let me know what you think!

Don’t forget! Reflection is slower than the normal means of accessing properties. While the time spent is negligible in small amounts, if you’re going to be using this code below with a lot of items, it may be wiser to define a class instead.

Source Code

Download AnonymousType.cs

New Version Available:Check out this post about the AnonymousType class Remixed!.

.

Written by hugoware

May 13, 2009 at 11:41 am