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