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] Add overload for Dictionary.TrytGetValue() to get ref value types. #3217

Closed
hurleybird opened this issue Feb 20, 2020 · 5 comments

Comments

@hurleybird
Copy link

hurleybird commented Feb 20, 2020

Eg:

public bool TryGetValue(TKey key, ref TValue value) where TValue : ValueType

Idea here is to avoid a currently necessary second access for value types that exists in a number of scenarios.

For example, say you have a dictionary of type <string, int> and an int i which you either want to add to an existing value, or assign as a new item if a key does not already exist.

Currently, this looks like:

if (dict.ContainsKey(key))
    dict[key] += i;
else
   dict[key] = i;

If the key exists we need to perform a second dictionary access, which isn't ideal. However, if we can use the ref keyword on the second TryGetValue parameter we're able to avoid the second access altogether. Eg:

if (dict.TryGetValue(key, ref int value))
    value += i;
else
    dict[key] = i;
@hurleybird hurleybird changed the title Add overload for Dictionary.TrytGetValue() to get ref value types. [Proposal] Add overload for Dictionary.TrytGetValue() to get ref value types. Feb 20, 2020
@dotjpg3141
Copy link

I don't think you proposed API would work.
What would happen if you delete the key while holding a reference to the value?

if (dict.TryGetValue(key, ref int value)) {
    dict.Remove(key);
    value += i;
} else {
    dict[key] = i;
}

@benaadams
Copy link
Member

Would be a .NET library proposal rather than a C# specific one; here's one for you 😉

dotnet/runtime#27062

@svick
Copy link
Contributor

svick commented Feb 20, 2020

The proposed API wouldn't work, because that's not how ref parameters work: you use them to pass a reference to a variable you provided into a method, you can't use them to get a reference to another variable back.

For that, you need ref returns and there is already a proposal to do this using that feature: dotnet/runtime#27062.

@dotjpg3141 You're right that this feature would be dangerous, the proposal I linked to above resolves that by "hiding" the method in a different class in an obscure namespace, in an attempt to ensure that you only use it if you understand those limitations.

@pinkfloydx33
Copy link

There's a DictionarySlim in experimental collections that provides something similar to what you want through GetOrAddValueRef though as a whole it's got some limitations

@hurleybird
Copy link
Author

That's right, that's not how ref paramters work. Total brain fart on my part!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants