TryGet Concepts
There are many concepts within Mutagen that are optional, nullable, or may not link up at runtime.
It is good practice to code in a way that is able to handle both situations:
- The field is not null. The lookup found its target. Etc
- The field is null. The lookup failed to find its target. Etc
To facilitate this, most API comes with Try
alternatives.
Direct Access
Let's first take a look at the non-Try route.
This pattern assumes your lookup will succeed. This is only safe if you checked that it existed earlier.
Mutagen Example
An example:
INpcGetter npc = ...;
IRaceGetter race = npc.Race.Resolve(someLinkCache);
This will work in 98% of scenarios, up until some user has an odd Npc that doesn't list a Race. Maybe it was a test Npc that isn't used anymore, so it's not a big deal, except for the fact that your code will now throw an exception. It cannot Resolve
the race and give you an object back, so it throws.
Generic C# Example
This is equivalent to using the Dictionary indexer directly
Dictionary<int, string> dict = new();
dict[23] = "Hello";
// I will throw
var str = dict[45];
TryGet Patterns Instead
Instead, a better pattern might be:
Mutagen Example
INpcGetter npc = ...;
if (npc.Race.TryResolve(someLinkCache, out var race))
{
System.Console.WriteLine($"Race was {race}");
}
else
{
// Did not find it. Return? Skip?
}
Often, if in a loop, the cleanest pattern is:
foreach (INpcGetter npc in someCollection)
{
// Look it up, otherwise go to next npc
if (!npc.Race.TryResolve(someLinkCache, out var race)) continue;
System.Console.WriteLine($"Race was {race}");
}
Generic C# Example
For the basic C# dictionary example, this would be the equivalent of:
Dictionary<int, string> dict = new();
dict[23] = "Hello";
if (dict.TryGetValue(45, out var str))
{
// Found it
}
Summary
It is almost always preferable to use the Try
alternative when available. It will force you to consider both when it finds what it was looking for, as well as the case when it does not.
Straight "Try
-less" calls should only be used when you've previously checked that the value exists. Then you know the call is safe, and so it's proper to not need to Try
. This is rarely used, as the Try
pattern both checks that it exists and gets the value in one swoop, so a followup retrieval is usually not needed.