MemberInitExpression fails to recognize needed explicit conversion from value type to object.

Open
#116,643 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
3/5
Estimated time
1-2 days
Newbie friendliness
45/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Stale
Tech stack
csharp
Domain
compilers

Research direction

Start by reproducing the issue with the provided Expression.Bind, MemberInit, and Lambda.Compile example, then inspect the validation path for Expression.Bind and compare it with the Expression.Convert workaround. Done means the invalid value-type-to-object binding is rejected with ArgumentException, with regression coverage for the reported case.

Written by the indexing model from the issue text.

Description

area-System.Linq.Expressions untriaged
Description

Hello,

while compiling an Expression Tree I encountered an error when compiling a it as a lambda:
System.InvalidProgramException: Common Language Runtime detected an invalid program.

After some painful debugging (the expression tree was a bit larger^^) I found out that Expression.Bind(...) argument validation only checks for assignability to the member that is being initialized.

However: If the member has type 'object' and the value I want to bind is any value-type, the compiler expects an explicit convert to object. I guess this is because of boxing??

So either I would expect the compiler to be able to bind a value-type variable to an object member or the validation for the arguments of Expression.Bind(...) should throw an exception that tells me that a binding form a value-type to an object requires an explicit cast, but not a compiler error with such little detail further down the line...

If call a method or constructor I will get an error when assigning a value-type to an object parameter, so this seems fine. As I stated, I would expect an error from Expression.Bind if I cannot perform such an assignment.

This whole thing happens because the validation only checks for memberType.IsAssignableFrom(expression.Type)

Reproduction Steps

using System.Linq.Expressions;

var parameter = Expression.Parameter(typeof(decimal));

var binding = Expression.Bind(
    typeof(Wrapper).GetProperty(nameof(Wrapper.Value))!,
    parameter
);

var init = Expression.MemberInit(
    Expression.New(typeof(Wrapper)), 
    binding
);

var lambda = Expression.Lambda(init, parameter);
var func = lambda.Compile();

return;

public class Wrapper
{
    public object? Value { get; set; }
}


Exception:
System.InvalidProgramException: Common Language Runtime detected an invalid program.
   at System.Reflection.Emit.DynamicMethod.CreateDelegate(Type delegateType, Object target)
   at System.Linq.Expressions.Compiler.LambdaCompiler.Compile(LambdaExpression lambda)
   at Program.<Main>$(String[] args)

Expected behavior

The comment for Expression.Bind states:
ArgumentException — member does not represent a field or property. -or- The property represented by member does not have a set accessor. -or- expression.Type is not assignable to the type of the field or property that member represents

I expect an Argument Exception when I am unable to assign a value-type to an object-member.

Actual behavior

No Exception is thrown. The error occurs once the lambda is being compiled.

Regression?

No response

Known Workarounds

Using Expression.Convert(...).

Configuration

.NET SDK 9.0.100
.NET 9.0
C# Version: 13

Other information

No response

Dominant language
C#
Stars
18.3k
Forks
5.6k
PR merge metrics
PR metrics pending

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from dotnet/runtime

All issues in dotnet/runtime

Similar issues

More C# issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.