Skip to content

API Change Request: Expression support for ref and readonly ref types #24884

Open
@JonHanna

Description

@JonHanna

Currently expressions represents ref types only in one place, viz. ParameterExpression objects for which IsByRef is true.

With a greater use of ref types due to greater language support, it seems fruitful to increase the availability of ref types in other expressions. While allowing such types directly on expressions' Type would be one reasonable approach (so that e.g. exp.Type == typeof(int).MakeByRefType() could be true) this has two problems:

  1. It doesn't play well with generics, and while generics aren't used in the typing of most expressions, they are important for the type of lambdas, so keeping ref-ness separate is probably cleaner.
  2. (More serious of the two, IMO). Doing this would not blend well with the current implementation of ParameterExpression.

There is also metadata support for ref types for which the address should not be written through (in parameters and ref readonly variables and returns in C#). It would be useful to be able to express this in expressions.

Note that #24621 would require such ref support as a prerequisite to making it available to Microsoft.CSharp.

This proposal suggests adding a IsByRef property to Expression similar to that of ParameterExpression (which would hide it in that case, but should return the save value) to represent ref types and an IsByRefReadOnly property to represent in/ref readonly types.

The default implementation is given as part of the proposal as that would affect custom classes derived from Expression.

IsByRefReadOnly only varies in the case where IsByRef is true. If IsByRef is false then IsByRefReadOnly should always be false.

GetDelegateType would need at least an internal overload that indicated the readonly quality of in parameters and ref readonly returns, so it should probably be made public.

The Parameter factory would similarly need to be able to indicate in parameters.

Other factories will depend on inferring such types, unless experience shows that explicit factories are beneficial.

namespace System.Linq.Expressions
{
    public partial class Expression
    {
        public static Type GetDelegateType(Type[] typeArgs, bool[] isReadOnlyRef);
        public virtual bool IsByRef { get; }
        public virtual bool IsByRefReadOnly { get; }
        public static ParameterExpression Parameter(Type type, bool isReadOnlyRef);
        public static ParameterExpression Parameter(Type type, bool isReadOnlyRef, string name);
    }

    public class ParameterExpression : Expression
    {
        public new bool IsByRef { get; } // new added to prevent CS0108
    }
}

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions