2012-08-29

Why I dislike DLR

It took me hours last night to work out why I was getting a null result from the Value property in the following code when accessed via IronPython

public interface ISomeInterface
{
decimal Value { get; }
}


How could a non nullable type possibly return a null (or “None”)?  It turns out that when I set my variable using the .NET scripting API



ScriptScope.SetVariable(variableName, (ISomeInterface)value);


The scripting engine still works on the implementing object rather than the interface.  This means that if my object has a method “DoSomethingThatScriptingShouldNotHaveAccessTo()” then scripting has access to it!



In my case this bit me because I had a Nullable<decimal> property called “Value”, and the Value property implemented explicitly for the interface looked like this



decimal ISomeInterface.Value
{
get
{
if (this.Value == null)
CalculateValue();
return this.Value;
}
}


In this case I expected the script to access the variable’s “Value” property via the interface declaration because that is how I typecast the value when setting the variable; but because the DLR accesses the object itself it was going directly to the class’s property itself and fetching a Nullable<Decimal> which of course was null.



The upshot of this is that if I want any kind of control over which methods my users can script I cannot simply have my objects implement specific interfaces, I have to create a facade class for each class I want API access to which has a subset of members and simply passes them through to the real object.  That is going to be a LOT of work!



The DLR should respect the type of the reference passed, not look up GetType() and work on that.  I need a static scripting language for .NET!

No comments: