As anyone familiar wth C# knows, you cannot use the as or is keyword to change or check types with the out var syntax.
For example, something like this is not possible:
var dictionary = new Dictionary<string, object>();
if (dictionary.TryGetValue("key", out as string val)) { }This project aims to address the above desired use case.
Package manager console:
install-package tryget
Dotnet CLI:
dotnet add package tryget
using TryGet;// Check if the key exists
if (dictionary.TryGet("key")) { }
// Check if the key exists and can be cast to string
if (dictionary.TryGet("key").As<string>()) { }
// Capture the value at key "key" if it exists and can be cast to string, otherwise default
var val = dictionary.TryGet("key").As<string>().OrDefault();
// Same as above, but with custom default value
var val = dictionary.TryGet("key").As<string>().OrDefault("Not a string.");
// Check if the key exists and capture the value with 'out' keyword
if (dictionary.TryGet("key").As<string>(out var val)) { }Let's set up our dictionary.
TryGet works on any IDictionary<TKey, TValue>, but it's most useful on <string, object> dictionaries commonly used to pass custom data.
We will assume this dictionary exists for our examples.
var dictionary = new Dictionary<string, object>
{
{ "key", new { } },
{ "string", "This is a string." },
{ "number", 15 }
};...exists
if (dictionary.TryGet("key"))
{
// "key" exists, do stuff
}...exists and is of a certain type
if (dictionary.TryGet("string").As<string>())
{
// "string" exists and is a string
}You can also check casts to polymorphic types.
class Animal { }
class Cat : Animal, IHasNineLives { }
class Dog : Animal { }
interface IHasNineLives { }
...
var animals = new Dictionary<string, Animal>
{
{ "cat", new Cat() },
{ "dog", new Dog() }
}
if (animals.TryGet("cat").As<Cat>())
{
// Success
}
if (animals.TryGet("cat").As<Dog>()}
{
// Not success
}Interfaces work too
if (animals.TryGet("cat").As<IHasNineLives>())
{
// Success
}
if (animals.TryGet("dog").As<IHasNineLives>())
{
// Not success
}I guess this works too if you're just a mad lad
if (animals.TryGet("cat").As<object>().As<Animal>().As<Cat>())
{
// Success
}...if it exists
var val = dictionary.TryGet("number");
// val = 15 (boxed to an object)...if it exists and is of a certain type, otherwise return the default
var val = dictionary.TryGet("number").As<int>().OrDefault();
// val = 15var val = dictionary.TryGet("number").As<string>().OrDefault();
// val = nullOrDefault() also supports custom default values
var val = dictionary.TryGet("number").As<string>().OrDefault("Not a string.");
// val = "Not a string."You can also perform a check and capture the value with out
if (dictionary.TryGet("number").As(out var val))
{
// val = 15 (boxed to an object)
}The real value-add here is being able to cast with out
if (dictionary.TryGet("number").As<int>(out var val)){
// val = 15
}Calling .TryGet() returns a result of type TryGetResult<TValue>, which can be used directly instead of the fluent methods.
var result = dictionary.TryGet("number");
if (result.IsSuccess)
{
// Success!
// Do something with result.Value
}The result also supports being cast directly to a compatible result type.
string stringValue = (string)result;The only type you cannot cast to is bool; this is a special case used for indicating success.
Value will throw a NoValueException if the key did not exist:
var result = dictionary.TryGet("does_not_exist");
var val = result.Value; // !!!It will also throw a NoValueException if the retrieved value was not the correct type:
var result = dictionary.TryGet("string").As<int>();
var val = result.Value; // !!!