Reputation: 60841
How can we implement pattern matching in order to return a tuple?
Currently method signature
public static string Match(string nodeName, string nodeValue, string sourceParty,
string destinationParty, List<Translation> translations)
Desired Method Signature
public static (string, TypeOfMatch) Match(string nodeName, string nodeValue,
string sourceParty, string destinationParty, List<Translation> translations)
I have the following static method:
public static class Matcher
{
public static string Match(string nodeName, string nodeValue, string sourceParty,
string destinationParty, List<Translation> translations)
{
//please excuse the pseudo code in these 3 lines
var exactMatch = from.translations(where xyz).select.Take(1)
var defaultMatch = from.translations.select(where abc).Take(1)
var anySourceMatch = from.translations.select(where sss).Take(1)
return exactMatch.FirstOrDefault() ??
defaultMatch.FirstOrDefault() ??
anySourceMatch.FirstOrDefault() ??
nodeValue;
}
}
I would like to know the type
of match that was returned (whether it was exact/default/anySource).
Right now we are returning string
, but perhaps the return should be a tuple such as (TypeOfMatch, string)
where TypeOfMatch
would be an enum such as:
public enum TypeOfMatch
{
Exact, Default, AnySource
}
but then our return statement would be something like:
if (exactMatch.FirstOrDefault() != null)
return (TypeOfMatch.Exact, exactMatch.First());
if (defaultMatch.FirstOrDefault() != null)
return (TypeOfMatch.Default, defaultMatch.First());
// etc.
Is there a more robust way of doing a switch
on which of the variables were not null and then returning the pair (TypeOfMatch, string)
?
Upvotes: 1
Views: 140
Reputation: 54897
The challenge with your scenario is that value tuples are value types, and therefore cannot be combined using the null-coalescing operator, ??
, which only works on nullable types. However, you could define an extension method to convert your value tuple into a nullable value type, which could then be subjected to ??
.
I am assuming that your Translation
class has an implicit type conversion to string
; otherwise, you need to call ToString()
or read a string property when constructing your value tuples.
public static class Matcher
{
public static (TypeOfMatch, string) Match(
string nodeName, string nodeValue, string sourceParty,
string destinationParty, List<Translation> translations)
{
return
translations.Where(xyz).Select(t => (TypeOfMatch.Exact, t)).FirstOrNull() ??
translations.Where(abc).Select(t => (TypeOfMatch.Default, t)).FirstOrNull() ??
translations.Where(sss).Select(t => (TypeOfMatch.AnySource, t)).FirstOrNull() ??
(TypeOfMatch.NodeValue, nodeValue);
}
}
public static class EnumerableExtensions
{
public static T? FirstOrNull<T>(this IEnumerable<T> source)
where T : struct
{
return source.Cast<T?>().FirstOrDefault();
}
}
Upvotes: 2