The following code:
(object ret, Expression subexpr) = expr switch {
// instance member
MemberExpression mexpr when mexpr.Expression is not null =>
(mexpr, mexpr.Expression),
// instance method call
MethodCallExpression callExpr when callExpr.Object is not null =>
(callExpr, callExpr.Object),
// include instance method calls, or static extension method calls
MethodCallExpression callExpr when
callExpr.Method.GetCustomAttributes(typeof(ExtensionAttribute)).Any() &&
callExpr.Arguments.FirstOrDefault() is not null =>
(callExpr, callExpr.Arguments.First()),
_ => (null, null)
};
does not compile, with:
CS8131: Deconstruct assignment requires an expression with a type on the right-hand-side.
Why is this happening? How can I fix it?
This seems like a simple case of "the compiler can't figure out the type of the switch". If you replace the deconstruction with a simple var x =
to let the compiler figure out what type the switch expressions should evaluate to, the error message changes to a much more useful:
No best type was found for the switch expression
The tuples that you return each case are of type:
(MemberExpression, Expression)
(MethodCallExpression, Expression)
(MethodCallExpression, Expression)
The compiler probably can't decide what common ancestor of MemberExpression
and MethodCallExpression
it should use.
Even a simple "hint" like this,
((object)mexpr, mexpr.Expression),
or:
((Expression)mexpr, mexpr.Expression),
so that the compiler doesn't need to find common ancestors, fixes the problem.
Instead of (null, null)
, use (default(object), default(Expression))
in order to help the compiler to guess the types of your right-hand-side expression.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With