I have a subclass of DynamicObject, where I implemented several implicit operators (for automatic conversions) and overriden some Try[OperationType] methods.
I get an exception when I try to make a add(+) operation with an object of that type (exception on the bottom of the question).
...
var d = GetDynamicObject();
int result = d + 1;
...
An answer that I thought would help with this question is this one. The behaviour described is correct, but my dynamic object has several static implicit operators defined, and I think the problem is with the string one. When I define the implicit operator for string, que add(+) operation throws an exception. I can observe by the stacktrace that the problem may be that he can't bind the operators, and I'm starting to think thats because some kind of add/concatenation confusion.
I simplified my code and wrote this test that I think it portrays the situation. When I comment the implicit operator for string, eveything works great.
Am I doing something wrong? Is there some method I need to override also? Any ideias?
public class Program
{
static void Main(string[] args)
{
try
{
var d = GetDynamicObject();
int result = d + 1;
Console.WriteLine("OK: " + result);
}
catch (Exception)
{
Console.WriteLine("Error!");
}
Console.ReadLine();
}
public static dynamic GetDynamicObject()
{
return new MyDynamicObject();
}
}
public class MyDynamicObject : DynamicObject
{
public static implicit operator int(MyDynamicObject obj)
{
return 0;
}
public static implicit operator long(MyDynamicObject obj)
{
return 0;
}
public static implicit operator double(MyDynamicObject obj)
{
return 0;
}
// Works when commented
public static implicit operator string(MyDynamicObject obj)
{
return null;
}
public override bool TryBinaryOperation(BinaryOperationBinder binder, object arg, out object result)
{
Console.WriteLine("MyDynamicObject.TryBinaryOperation");
return base.TryBinaryOperation(binder, arg, out result);
}
}
The Exception:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderInternalCompilerException was unhandled
HResult=-2146233088
Message=An unexpected exception occurred while binding a dynamic operation
Source=Microsoft.CSharp
StackTrace:
at Microsoft.CSharp.RuntimeBinder.Semantics.ExpressionBinder.WhichSimpleConversionIsBetter(PredefinedType pt1, PredefinedType pt2)
at Microsoft.CSharp.RuntimeBinder.Semantics.ExpressionBinder.WhichTypeIsBetter(PredefinedType pt1, PredefinedType pt2, CType typeGiven)
at Microsoft.CSharp.RuntimeBinder.Semantics.ExpressionBinder.WhichBofsIsBetter(BinOpFullSig bofs1, BinOpFullSig bofs2, CType type1, CType type2)
at Microsoft.CSharp.RuntimeBinder.Semantics.ExpressionBinder.FindBestSignatureInList(List`1 binopSignatures, BinOpArgInfo info)
at Microsoft.CSharp.RuntimeBinder.Semantics.ExpressionBinder.BindStandardBinop(ExpressionKind ek, EXPR arg1, EXPR arg2)
at Microsoft.CSharp.RuntimeBinder.RuntimeBinder.BindBinaryOperation(CSharpBinaryOperationBinder payload, ArgumentObject[] arguments, Dictionary`2 dictionary)
at Microsoft.CSharp.RuntimeBinder.RuntimeBinder.DispatchPayload(DynamicMetaObjectBinder payload, ArgumentObject[] arguments, Dictionary`2 dictionary)
at Microsoft.CSharp.RuntimeBinder.RuntimeBinder.BindCore(DynamicMetaObjectBinder payload, IEnumerable`1 parameters, DynamicMetaObject[] args, DynamicMetaObject& deferredBinding)
at Microsoft.CSharp.RuntimeBinder.RuntimeBinder.Bind(DynamicMetaObjectBinder payload, IEnumerable`1 parameters, DynamicMetaObject[] args, DynamicMetaObject& deferredBinding)
at Microsoft.CSharp.RuntimeBinder.BinderHelper.Bind(DynamicMetaObjectBinder action, RuntimeBinder binder, IEnumerable`1 args, IEnumerable`1 arginfos, DynamicMetaObject onBindingError)
at Microsoft.CSharp.RuntimeBinder.CSharpBinaryOperationBinder.FallbackBinaryOperation(DynamicMetaObject target, DynamicMetaObject arg, DynamicMetaObject errorSuggestion)
at System.Dynamic.DynamicObject.MetaDynamic.<>c__DisplayClass9_0.<BindBinaryOperation>b__0(DynamicMetaObject e)
at System.Dynamic.DynamicObject.MetaDynamic.CallMethodWithResult(String methodName, DynamicMetaObjectBinder binder, Expression[] args, Fallback fallback, Fallback fallbackInvoke)
at System.Dynamic.DynamicObject.MetaDynamic.BindBinaryOperation(BinaryOperationBinder binder, DynamicMetaObject arg)
at System.Dynamic.BinaryOperationBinder.Bind(DynamicMetaObject target, DynamicMetaObject[] args)
at System.Dynamic.DynamicMetaObjectBinder.Bind(Object[] args, ReadOnlyCollection`1 parameters, LabelTarget returnLabel)
at System.Runtime.CompilerServices.CallSiteBinder.BindCore[T](CallSite`1 site, Object[] args)
at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0 arg0, T1 arg1)
at WIG.Common.Tests.Program.Main(String[] args) in C:\WIG\WIG Framework\Dev\WIG.Common.Tests\Program.cs:line 74
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException: