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

[API Proposal]: Supporting collection expression [] for empty ReadOnlyCollection<T>.Empty #110942

Closed
AlexRadch opened this issue Dec 25, 2024 · 2 comments
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Collections

Comments

@AlexRadch
Copy link
Contributor

Background and motivation

The ReadOnlyCollection<T> type in C# is a widely used wrapper for ensuring the immutability of collections from consumers. It is commonly used to expose collection data in APIs while guaranteeing that consumers cannot modify it. However, working with empty instances of ReadOnlyCollection<T> often requires verbose syntax that diminishes readability and convenience in codebases where immutability and empty collections are frequent.

Currently, to assign an empty ReadOnlyCollection<T>, developers must use the static property ReadOnlyCollection<T>.Empty or construct an empty instance manually using a backing empty array. This verbosity can lead to less concise and harder-to-read code. For example:

ReadOnlyCollection<int> collection = ReadOnlyCollection<int>.Empty;

In contrast, C# already provides a concise and elegant syntax for empty arrays using the collection expression [], which is translated to Array.Empty<T>() when appropriate. Introducing support for the same [] syntax for ReadOnlyCollection<T>.Empty would offer the following benefits:

  1. Improved Developer Experience
    The [] syntax simplifies code by reducing boilerplate when working with immutable empty collections. This improves readability, especially in scenarios involving complex data structures or configuration setups where immutability is key.

  2. Symmetry and Consistency Across Collection APIs
    Supporting [] for ReadOnlyCollection<T>.Empty aligns with existing patterns in C# for empty arrays (Array.Empty<T>()) and other concise initializations (e.g., new List<int>() or LINQ .ToList() calls). This symmetry enhances the intuitiveness of the language.

  3. Encouraging Best Practices with Immutability
    Many APIs recommend returning immutable empty collections instead of null to reduce the risk of null reference exceptions. By making immutable empty collections easier to use, this feature promotes better programming practices.

  4. Prevalence of Empty Collections in Real-World Scenarios
    Use cases for immutable empty collections are common, including:

    • Default parameters for methods or constructors.
    • Return values for APIs where no data is present.
    • Placeholder values for collections in algorithms and frameworks.
  5. Reduction of Boilerplate Code
    Consider the following example:

    ReadOnlyCollection<int> collection = condition ? ReadOnlyCollection<int>.Empty : someOtherCollection;

    With the proposed feature, this can be simplified to:

    ReadOnlyCollection<int> collection = condition ? [] : someOtherCollection;

    This reduction in boilerplate code makes the developer’s intent clearer and the code more readable.

By enabling the collection expression [] to represent ReadOnlyCollection<T>.Empty, the language gains a powerful tool for expressing immutability succinctly while maintaining consistency with existing patterns in C#.

API Proposal

Enable the following syntax for creating an immutable empty ReadOnlyCollection<T>:

ReadOnlyCollection<int> collection = [];

The collection expression [], when assigned to a ReadOnlyCollection<T>, will be translated to a reference to the existing singleton instance of ReadOnlyCollection<T>.Empty. Internally, this will leverage the following implementation:

ReadOnlyCollection<int> collection = ReadOnlyCollection<int>.Empty;

This ensures that the [] syntax remains consistent with other uses of empty collections in C# while maintaining high performance and memory efficiency by reusing the singleton instance.

API Usage

1. Variable Initialization

The [] expression can be used to initialize an empty ReadOnlyCollection<T> directly, making the code concise and readable.

ReadOnlyCollection<int> collection = [];

2. Method Parameters

The [] syntax can be used to set default values for ReadOnlyCollection<T> parameters.

void ProcessItems(ReadOnlyCollection<int> items = [])
{
    // Process items
}

3. Return Values

You can use the [] expression to return an immutable empty collection from methods.

ReadOnlyCollection<int> GetEmptyCollection()
{
    return [];
}

4. Conditional Expressions

The [] syntax works seamlessly in conditional expressions for initializing empty collections based on a condition.

ReadOnlyCollection<int> collection = condition ? [] : someOtherCollection;

5. LINQ and Transformations

The [] expression simplifies scenarios where you need to return an empty immutable collection based on a LINQ query result.

ReadOnlyCollection<int> filtered = results.Any() 
    ? results.Where(x => x > 0).ToList().AsReadOnly() 
    : [];

6. Nested Initializations

The [] syntax can be used in nested object initializations, such as for default properties or fields.

class Example
{
    public ReadOnlyCollection<int> Items { get; set; } = [];
}

Summary of Benefits

  • Conciseness: Eliminates the need for verbose ReadOnlyCollection<T>.Empty.
  • Readability: Makes code more expressive and intuitive.
  • Consistency: Aligns with Array.Empty<T>() and other modern collection initialization patterns in C#.
  • Usability: Simplifies common scenarios, especially when dealing with method defaults, conditionals, and APIs.

Alternative Designs

No response

Risks

No response

@AlexRadch AlexRadch added the api-suggestion Early API idea and discussion, it is NOT ready for implementation label Dec 25, 2024
@dotnet-policy-service dotnet-policy-service bot added the untriaged New issue has not been triaged by the area owner label Dec 25, 2024
Copy link
Contributor

Tagging subscribers to this area: @dotnet/area-system-collections
See info in area-owners.md if you want to be subscribed.

@eiriktsarpalis
Copy link
Member

Duplicate of #110161

@eiriktsarpalis eiriktsarpalis marked this as a duplicate of #110161 Dec 25, 2024
@dotnet-policy-service dotnet-policy-service bot removed the untriaged New issue has not been triaged by the area owner label Dec 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Collections
Projects
None yet
Development

No branches or pull requests

2 participants