Member Exists – Dynamic C# 4.0

I have been using the dynamic keyword a little bit in C# and I have recently run into a small problem and I have been trying to figure out the most elegant way to resolve it. The problem is, when you try to invoke a member that does not exist on a dynamic object it throws an exception, there is no easy way to detect if the member exists built-in to accommodate this.

For example what I would really like is an ‘exists’ keyword, something like:

dynamic instance = new { Foo = "Hello World!" };
if (exists(instance.Foo))
{
Console.WriteLine(instance.Foo);
}

But there appears to be no magic ‘exists’. Turns out the only way to do this is with reflection. So I created some helper extension methods to enable the following example:

object instance = new { Foo = "Hello World!" };

if (instance.Reflection().Exists().Foo)
{
    string value = instance.Reflection().Call().Foo;
    Console.WriteLine(value);
}

Interestingly enough the Foo in this case is a call to a DynamicObject I created that can intercept calls to members and returns a bool if they exist, never calling them. The Reflection().Call() simply casts any object into a dynamic object for dynamic calling.

I also found out that you can’t use the dynamic Type as the first parameter in an extension method. Dynamic objects and extension methods don’t really play together very nicely.

Download the full example here:

https://onedrive.live.com/redir?resid=DFCD2D88D3FE101C%21341

LambdaExpression.CompileToMethod … not nearly as cool as I had hoped.

I was messing around with the new dynamic expressions in C# 4 (found in System.Linq.Expressions). One new thing I noticed was the method CompileToMethod on LambdaExpressoin. The first parameter is a MethodBuilder so I got really excited, finally an easy way to create dynamic methods on Types!

Wrong, turns out the method has to be Static, also it cannot accept, as a parameter, the Type the method is being built on. So this basically completely negates the entire purpose. At this point you might as well simply compile it to a delegate and use that instead. Bummer.

Here is an explanation of why:

After much investigation, it turns out this is by won’t fix for CLR 4.0

You can’t use expression trees to model instance methods or constructors. First problem: you can’t create the “this” parameter, because all you have in hand is a TypeBuilder, but that is not the final type. We can create a delegate with the TypeBuilder, but CLR won’t let us create a LambdaExpression with that delegate (because the type is not finished). You can workaround that by making the “this” parameter be of type object, then you end up with meaningless casts. Worse, calls to your own methods don’t work, because MethodBuilder doesn’t implement enough of reflection for expression trees to do their normal sanity checks.

DynamicMethods run into their own problems. When emitting into a DynamicMethod, we can’t add our Closure argument to the signature of the DynamicMethod. Without a closure,

  • DynamicMethods run into some serious limiations:
    They can’t have nested lambdas at all (due to a CLR limitation: can’t ldftn to a DynamicMethod).
  • Some things that are O(1) or amortized O(1) become O(N), such as RuntimeVariables and Switch on strings. This is really sneaky for the user who won’t expect things to suddenly be slower.

This needs work we plan for ETs v3, and the design around the support will likely change.

One potential work around I have contemplated but haven’t gotten up the energy to try would be to try to generate a matching interface first, then pass that around as a parameter to the static method. You’d have to give access to all fields through explicitly implemented properties though, destroying encapsulation in the process. So if suppose you wanted to generate something like this:

public class Test
{
    private int foo;

    public int Bar()
    {
        return this.foo;
    }
}

Instead you would generate something like this:

public interface ITest
{
    int foo { get; set; }

    int Bar();
}

public class Test : ITest
{
    private int foo;

    int ITest.foo
    {
        get { return this.foo; }
        set { this.foo = value; }
    }

    public int Bar()
    {
        return Test.Bar(this);
    }

    public static int Bar(ITest test)
    {
        return test.foo;
    }
}

The benefits of using the Linq expressions to build your method bodies quickly diminish with this sort of workaround however. You might as well just go back to the ILGenerator (*shudders*). This would probably work because the static Bar method can accept a parameter of a Type already dynamically created.

CSharp Optionally Dynamic Calls

I’ve been reading about how the C# team is considering putting the option to call dynamic code within C# directly and I have been looking at some of the syntax they have been proposing publicly. It also seems like there are a handful of people who are proposing their own ideas of how to express various features of C# they wish existed so I thought I’d propose one of my own.

Personally I find the idea of a dynamic method or a dynamic block a little clunky. So I would like to propose a different possible solution.

The whole idea is that in C# the compiler has to know the type of a variable so it can guarantee that the method you are trying to call exists. This is largely the purpose of interfaces. However, there are some circumstances where you might prefer to call a method dynamically. The dynamic method block syntax Charlier Calvert is proposing is very reminiscent of the “unsafe” synatx in C# however if you really wanted to make the language more dynamic in general I think you could simply have the option to call the memeber with something other than a ‘.’ to indicate that it should be a dynamic call. Something more like:

string example = obj:Example();

In this case I’m suggesting that merely replacing the ‘.’ with a ‘:’ will cause the application to call the Example method dynamically. I belive this would still conform to the explicit nature of C# while making dynamic calls quite flexible. If the colon was an undesierable character it would be simple enough to just use something else.

In this case you would not get much intellisense related to the parameters or return value of Example wich I believe would prevent it from being used except in circumstances where it was absolutely needed. Also you would only get runtime exceptions if the types of the parameters and return values were incorrect. It would probably have to assume that the return Type was actually an object if you used the “var” syntax.

Also, you would need some way to check to see if the member existed at the very least:

string example;
if(exists(obj:Example))
   example = obj:Example();

Of course, this should be essentially the same for fields, properties and events. For example:

string example = obj:Example; // field or property
obj:ExampleEvent += new EventHandler(OnExampleEvent);

Dynamic SQL for NBusiness

I have been working on adding the ability to do dynamic SQL for NBusiness business objects. The point of this basically to allow a developer to quickly add new Fetch factories. Currently if you want to add a new fetch factory you need to do a few steps.

·         Create the factory method

·         Create the Criteria class

·         Add a handler to the Fetching event

·         Add a case to the fetching handler for your criteria object

·         Then call the Database Provider

·         Create the necessary stored procedure

Since needing to create new Fetch factories is a pretty common task I wanted to add a way to make it easier. NBusiness will generate all of the most common Factories and stored procedures for you (such as factories for fetching all entities or fetching by id’s or relationships) but if you want to be able to fetch by some other column type you’re stuck with creating your custom factories. For example if you wanted to search for all Customers with the first name of “justin” you’d need to create a FetchByFirstName(string name) factory.

So now rather than going through all of the steps above you can simple create your Fetch factory using dynamic SQL and pass that into the Database Provider instead. There is an object model for creating this dynamic SQL and NBusiness default templates will generate for you all of the Table and Column objects corresponding to your entities.

So for example if you have a Customer entity and you want to fetch by first name you might create a factory method that looks like this:

public static TopicCollection FetchByFirstName(string name)

{

    IQuery query = Topic.Queryable.Table.Where(

        Topic.Queryable.Name == “@name”);

       

    return new TopicCollection(

        query,

        new Parameter(“@name”, name));

}

NOTE: exact syntax may change; this is just an example of how I have it now.

Also, when we upgrade to Visual Studio 2008 these objects will be LINQ queryable. Meaning if you query your entities within a LINQ statement it will generate dynamic SQL for you to fetch the data for your entities (yes, like DLINQ).

Different Database providers will be able to implement their own Query classes so that SQL can be generated for different types of databases. For now I will just implement it for SqlServer 2005, in fact I’m probably going to push back the release of the MySql provider stuff just because as far as I know there isn’t really a demand for it at this point and it’s more work than it’s worth given that fact.