Roslyn: Proposal: Take ref return into consideration during overload resolution

Created on 28 Nov 2016  路  5Comments  路  Source: dotnet/roslyn

In the past when C# team "banned" resolution on left side of members, ref return did not exist, so this specific case was never considered.

Now ref return is making his way in and i propose to consider making exception for this specific case in overloading resolution path. C# is in comfort situation since C# require ref keyword everywhere you want to call or define ref returning member which should simplify grabbing appropiate candidates to call: check ref existence, if exist discard all non-ref-returning, otherwise discard all ref-returning candidates and proceed as usual.

Benefits? Take Dictionary<> as example: Today, in order to offer fast path for Dictionary<>'s indexer, one have to copy whole Dictionary<> and make separate RefReturningDictionary<>. This may be contrived example but is first that came to me.

With ref taken into account during overload resolution this wont be necessary; just copy-paste indexer and make appropiate adjustments (because non ref returning implementation doesnt always translate straightforwardly into ref returning one).

The only cons i can imagine is that for reference types there is practically zero benefits and can cause confusion for beginners in this specific situation (for value types benefits are clear).

Thoughts?

Area-Language Design Discussion Language-C#

Most helpful comment

Sounds like this proposal is to allow overloading based on return values but only between ref and non-ref types:

public struct Foo {
    private int field;

    // method 1
    public int M() {
        return this.field;
    }

    // method 2
    public ref int M() {
        return ref this.field;
    }
}

...

int x = M(); // calls method 1
ref int y = M(); // calls method 2

But the proposal also implies allowing this for properties/indexers and I'm not sure that CLR metadata would even allow for that.

All 5 comments

@BreyerW I can't tell if you have a specific proposal, or you're just interested in a discussion on the topic. It is very late, but still possible, to make changes for C# 7.

We had intended to allow calling a ref-returning method in a value (non-ref) context. Are you suggesting we forbid that?

Sounds like this proposal is to allow overloading based on return values but only between ref and non-ref types:

public struct Foo {
    private int field;

    // method 1
    public int M() {
        return this.field;
    }

    // method 2
    public ref int M() {
        return ref this.field;
    }
}

...

int x = M(); // calls method 1
ref int y = M(); // calls method 2

But the proposal also implies allowing this for properties/indexers and I'm not sure that CLR metadata would even allow for that.

Exactly what @HaloFour said.

However, given that you already support implicit dereference to non-ref variable (which, admittely, i didnt taken into account) there may be little to no point in my proposal. Maybe for old libraries that must have at least modifications as possible and favor additions to modifications when upgrading to newer c# but thats all.

Im personally concerned about collections. Will they have indexers changed or because of compatibility they gonna be duplicated with added ref where applicable? But that probably issue/questions for coreFX?

@BreyerW

Im personally concerned about collections. Will they have indexers changed or because of compatibility they gonna be duplicated with added ref where applicable? But that probably issue/questions for coreFX?

Existing collections couldn't have their indexers modified as that would be a breaking change. A ref type is actually a different type to the CLR. My assumption is that the majority of existing collections would be unsuitable for ref indexers due to their internal implementations anyway. Even List<T>, which is backed by an array, runs the risk of orphaning any ref it would return if the collection is modified.

Was this page helpful?
0 / 5 - 0 ratings