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!
Comments