Skip to content

An inref<_> returned by a property or method is weirdly behaving in C# #9997

@teo-tsirpanis

Description

@teo-tsirpanis

Problem

F# code that defines a method or property with a readonly return byref using an inref is not usable from C#.

Details

Consider the following snippet:

type C() =
    let x = 59
    member _.X: inref<_> = &x

The emitted code is missing an attribute

 .custom instance void System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = ( 01 00 00 00 ) 

Sample solution

ClassLibrary4 (2).zip

It is compiled to this C# code:

[Serializable]
[CompilationMapping(SourceConstructFlags.ObjectType)]
public class C
{
    internal int x;

    public ref int X
    {
        get
        {
            return ref x;
        }
    }

    public C()
    {
        x = 0;
    }
}

X is seen as a read-write byref by C#, not as a readonly ref. This subtle bug could bite the unsupecting C# consumer of a public library.

A C# code file referencing the first F# snippet and containing these statements:

using System;
static class Program {
    public static vod Main() {
        var c = new C();
        Console.WriteLine(c.X);
    }
}

The C# program does not compile! It displays Error CS0570 : 'C.X.get' is not supported by the language.

Workaround

The workaround is to add the IsReadOnly attribute manually:

open System.Runtime.CompilerServices

type C() =
    let x = 59
    
    
    member _.X(): [<IsReadOnly>] inref<_> = &x

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugImpact-Medium(Internal MS Team use only) Describes an issue with moderate impact on existing code.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions