Skip to content

Add an OrderedDictionary.TryAdd overload that returns the int-based index of an entry if the key already exists #107947

Open

Description

Motivation

The CollectionsMarshal.GetValueRefOrAddDefault method for dictionaries provides a powerful mechanism for adding or updating a dictionary entry using only one lookup. The newly added OrderedDictionary<TKey, TValue> collection would similarly benefit from a such an API, however we don't need to make it as unsafe; simply knowing the int-based index of an entry makes it possible to very cheaply look up or update its value using the GetAt and SetAt methods, respectively.

API Proposal

namespace System.Collections.Generic;

public partial class OrderedDictionary<TKey, TValue>
{
    public bool TryAdd(TKey key, TValue value);
+   public bool TryAdd(TKey key, TValue value, out int index);
}

API Usage

See this conversation for a motivating use case.

Before

if (!dict.TryAdd(propertyName, value))
{
    int index = dict.IndexOf(propertyName); // Second lookup operation
    Debug.Assert(index >= 0);
    JsonNode? replacedValue = dict.GetAt(index).Value;
    DetachParent(replacedValue);
    dict.SetAt(index, value);
}

After

if (!dict.TryAdd(propertyName, value, out int index))
{
    JsonNode? replacedValue = dict.GetAt(index).Value;
    DetachParent(replacedValue);
    dict.SetAt(index, value);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions