-
Couldn't load subscription status.
- Fork 840
Add AdditionalPropertiesDictionary.TryGetValue<T> #5528
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
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -4,6 +4,8 @@ | |||||
| using System; | ||||||
| using System.Collections; | ||||||
| using System.Collections.Generic; | ||||||
| using System.Diagnostics.CodeAnalysis; | ||||||
| using System.Globalization; | ||||||
| using System.Linq; | ||||||
|
|
||||||
| namespace Microsoft.Extensions.AI; | ||||||
|
|
@@ -45,7 +47,7 @@ public AdditionalPropertiesDictionary(IEnumerable<KeyValuePair<string, object?>> | |||||
| /// A shallow clone of the properties dictionary. The instance will not be the same as the current instance, | ||||||
| /// but it will contain all of the same key-value pairs. | ||||||
| /// </returns> | ||||||
| public AdditionalPropertiesDictionary Clone() => new AdditionalPropertiesDictionary(_dictionary); | ||||||
| public AdditionalPropertiesDictionary Clone() => new(_dictionary); | ||||||
|
|
||||||
| /// <inheritdoc /> | ||||||
| public object? this[string key] | ||||||
|
|
@@ -94,6 +96,9 @@ public object? this[string key] | |||||
| /// <inheritdoc /> | ||||||
| public IEnumerator<KeyValuePair<string, object?>> GetEnumerator() => _dictionary.GetEnumerator(); | ||||||
|
|
||||||
| /// <inheritdoc /> | ||||||
| IEnumerator IEnumerable.GetEnumerator() => _dictionary.GetEnumerator(); | ||||||
|
|
||||||
| /// <inheritdoc /> | ||||||
| public bool Remove(string key) => _dictionary.Remove(key); | ||||||
|
|
||||||
|
|
@@ -103,6 +108,46 @@ public object? this[string key] | |||||
| /// <inheritdoc /> | ||||||
| public bool TryGetValue(string key, out object? value) => _dictionary.TryGetValue(key, out value); | ||||||
|
|
||||||
| /// <inheritdoc /> | ||||||
| IEnumerator IEnumerable.GetEnumerator() => _dictionary.GetEnumerator(); | ||||||
| /// <summary>Attempts to extract a typed value from the dictionary.</summary> | ||||||
| /// <typeparam name="T">Species the type of the value to be retrieved.</typeparam> | ||||||
| /// <param name="key">The key to locate.</param> | ||||||
| /// <param name="value">The value retrieved from the dictionary, if found; otherwise, default.</param> | ||||||
| /// <returns>True if the value was found and converted to the requested type; otherwise, false.</returns> | ||||||
| /// <remarks> | ||||||
| /// If a value is found for the key in the dictionary, but the value is not of the requested type but is | ||||||
| /// an <see cref="IConvertible"/> object, the method will attempt to convert the object to the requested type. | ||||||
| /// </remarks> | ||||||
| public bool TryGetValue<T>(string key, [NotNullWhen(true)] out T? value) | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we explicitly ban nullable type parameters?
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What does that help? The parameter is already nullable in the case of reference types. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It explicitly prevents passing nullable type parameters even if it doesn't change the nullability of the out parameter. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right, but what benefit does that provide here? What errors does it avoid? It seems like it'd only be a hindrance here, eg not being able to use this in a method with an unconstrained T. This T is only ever in an out position, and the out is already nullable regardless of the T. |
||||||
| { | ||||||
| if (TryGetValue(key, out object? obj)) | ||||||
| { | ||||||
| switch (obj) | ||||||
| { | ||||||
| case T t: | ||||||
| // The object is already of the requested type. Return it. | ||||||
| value = t; | ||||||
| return true; | ||||||
|
|
||||||
| case IConvertible: | ||||||
| // The object is convertible; try to convert it to the requested type. Unfortunately, there's no | ||||||
| // convenient way to do this that avoids exceptions and that doesn't involve a ton of boilerplate, | ||||||
| // so we only try when the source object is at least an IConvertible, which is what ChangeType uses. | ||||||
| try | ||||||
| { | ||||||
| value = (T)Convert.ChangeType(obj, typeof(T), CultureInfo.InvariantCulture); | ||||||
| return true; | ||||||
| } | ||||||
| catch (Exception e) when (e is ArgumentException or FormatException or InvalidCastException or OverflowException) | ||||||
| { | ||||||
| // Ignore known failure modes. | ||||||
| } | ||||||
|
|
||||||
| break; | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| // Unable to find the value or convert it to the requested type. | ||||||
| value = default; | ||||||
| return false; | ||||||
| } | ||||||
| } | ||||||
This file was deleted.
This file was deleted.
Uh oh!
There was an error while loading. Please reload this page.