dotnet/roslyn

Exception in scripting when calling a method with void return via dynamic

Open

#42,497 opened on Mar 17, 2020

View on GitHub
 (0 comments) (1 reaction) (0 assignees)C# (4,257 forks)batch import
Area-InteractiveBugInteractive-ScriptingLogichelp wanted

Repository metrics

Stars
 (20,414 stars)
PR merge metrics
 (Avg merge 6d 17h) (256 merged PRs in 30d)

Description

Version Used:

3.5.0

Steps to Reproduce:

In Roslyn scripting, if a method with a void return is invoked via a dynamic property then an exception is thrown. If the actual type is used instead of dynamic then the method is called without problem:

    public static class Program
    {
        static async Task Main(string[] args)
        {
            var context = new ScriptContext();
            var options = ScriptOptions.Default.AddReferences(Assembly.GetAssembly(typeof(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo)));
            await CSharpScript.RunAsync("Foo.Bar()", options, context);
        }

        public class ScriptContext
        {
            public dynamic Foo { get; } = new Foo();
        }

        public class Foo
        {
            public void Bar()
            {
            }
        }
    }

Note that adding a ; allows the method to execute. The ; is not required without dynamic though.

Expected Behavior:

The method Foo.Bar() should run, or at least a useful error message should be thrown.

Actual Behavior:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException
  HResult=0x80131500
  Message=Cannot implicitly convert type 'void' to 'object'
  Source=System.Linq.Expressions
  StackTrace:
   at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
   at Submission#0.<<Initialize>>d__0.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.CodeAnalysis.Scripting.ScriptExecutionState.<RunSubmissionsAsync>d__9`1.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at Microsoft.CodeAnalysis.Scripting.Script`1.<RunSubmissionsAsync>d__21.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at ReplRepro.Program.<Main>d__0.MoveNext() in D:\temp\ReplRepro\ReplRepro\Program.cs:line 15

Contributor guide