0

Given the following code:

using System;
using System.Linq.Expressions;

Console.WriteLine(Expression.Lambda<Func<string>>(Expression.TryFault(Expression.Constant("hi"), Expression.Constant("alternative"))).Compile()());

I am targeting net462 (repro project here).

Unhandled Exception: System.NotSupportedException: The requested operation is invalid for DynamicMethod.
   at System.Reflection.Emit.DynamicILGenerator.BeginFaultBlock()
   at System.Linq.Expressions.Compiler.LambdaCompiler.EmitTryExpression(Expression expr)
   at System.Linq.Expressions.Compiler.LambdaCompiler.EmitExpression(Expression node, CompilationFlags flags)
   at System.Linq.Expressions.Compiler.LambdaCompiler.EmitLambdaBody(CompilerScope parent, Boolean inlined, CompilationFlags flags)
   at System.Linq.Expressions.Compiler.LambdaCompiler.Compile(LambdaExpression lambda, DebugInfoGenerator debugInfoGenerator)
   at System.Linq.Expressions.Expression`1.Compile()
   at Program.<Main>$(String[] args)

Why isn’t this emission supported?

I know that my example here is not a good example of when one would want to use Expression.TryFault(). However, the semantics fit exactly what I want in a certain scenario (running some code only if an exception is thrown by a particular expression without actually catching the original exception (I am actually trying to generate a more specific exception by rerunning parts of the original expression in a bunch of try/catch with the idea that the exception case will be exceptional and rarely run)).

Why does netfx throw here? I thought that even though C# doesn’t support fault blocks, netfx did. What is DynamicMethod and why is it special? Is there any suggestion for a way to express these semantics without encountering this error?

8
  • Why isn’t X supported? is off topic here Commented Sep 15, 2022 at 0:48
  • Can you write try{ "value" }catch(Exception e){ "other value" } in C#? Exception handling can't be used like a conditional ?: operator. You need to emit statements, not expressions. In other words the stack offset must be zero. Commented Sep 15, 2022 at 1:24
  • Well you might be able to use try / catch that way. But you can't use try / fault that way. Commented Sep 15, 2022 at 1:31
  • @JeremyLakeman You can do a lot of things in expressions which you can’t do in C#. In expressions, blocks evaluate to a value. Commented Sep 15, 2022 at 5:34
  • @stuartd It works fine in netcore which, IIRC, implements Expression.Lambda<>.Compile() using reflection. Also, the error is at a different layer—I had gotten past all of the expression validation errors and now the IL emission layer is doing something. This sort of issue feels a lot like getting BadImageFormatException which shouldn’t happen/indicates a bug or quirk in the framework for which I need advice for workarounds or just general information on what I might be doing oddly or wrong to trigger this behavior. Commented Sep 15, 2022 at 5:38

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.