Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Proposal] Generic indexers #523

Closed
sharwell opened this issue Feb 15, 2015 · 3 comments
Closed

[Proposal] Generic indexers #523

sharwell opened this issue Feb 15, 2015 · 3 comments

Comments

@sharwell
Copy link
Member

C# does not currently allow the definition of generic indexer properties. In addition, the CLR metadata tables do not provide a way to express a generic indexer property.

Motivating example

Say you have a strongly-typed OptionKey<T> for declaring options. The generic type T represents the type of value associated with a particular key.

public static class DefaultOptions
{
    public static OptionKey<bool> SomeBooleanOption { get; }
    public static OptionKey<int> SomeIntegerOption { get; }
}

Where options are exposed through the IOptions interface:

public interface IOptions
{
    T GetOptionValue<T>(OptionKey<T> key);
    void SetOptionValue<T>(OptionKey<T> key, T value);
}

Code could then use the generic indexer as a nice strongly-typed options store:

void Foo()
{
    IOptions o = ...;
    o.SetOptionValue(DefaultOptions.SomeBooleanOption, true);
    int integerValue = o.GetOptionValue(DefaultOptions.SomeIntegerOption);
}

The code above is reminiscent of Java, where "properties" do not have any special syntax. If C# supported generic indexers, the above code could instead be written as follows:

public interface IOptions
{
    T this<T>[OptionKey<T> key]
    {
        get;
        set;
    }
}

void Foo()
{
    IOptions o = ...;
    o[DefaultOptions.SomeBooleanOption] = true;
    int integerValue = o[DefaultOptions.SomeIntegerOption];
}

Language vs. Runtime

Like most requests for new features in a language, it is possible for the compiler to offer support by simply "lowering" the semantics to a form that the underlying runtime supports. However, in this particular case I believe the motivating example provides similar benefits to other languages which target the same runtime, so updating the metadata format to directly express generic indexers could be advantageous especially for scenarios involving assemblies written in multiple languages.

Note that the metadata format already allows the accessor methods to include generic type parameters; it is only the property metadata that needs to be updated.

Remaining issues

The primary remaining issue is the explicit specification of generic type arguments at the call site. In the examples above, type inference was used for both getting and setting property values. At first glance, syntax like the following might work, but I have not performed a rigorous evaluation of this in the context of the complete language specification.

void Foo()
{
    IOptions o = ...;
    o<bool>[DefaultOptions.SomeBooleanOption] = true;
    int integerValue = o<int>[DefaultOptions.SomeIntegerOption];
}
@paulomorgado
Copy link

The object<type>[index] syntax, although something we are not used to, might work.

I wonder if it could be extended to non indexed properties: object.Property<type>.

@aluanhaddad
Copy link

I think this would be very useful. In particular it would enable some nice scenarios for DSLs.

@gafter
Copy link
Member

gafter commented Mar 20, 2017

We are now taking language feature discussion on https://github.com/dotnet/csharplang for C# specific issues, https://github.com/dotnet/vblang for VB-specific features, and https://github.com/dotnet/csharplang for features that affect both languages.

@gafter gafter closed this as completed Mar 20, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants