Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Capturing which left hand item in the null-coalescing operator successfully assigned variable

Tags:

c#

I'm using the ?? operator to try and assign an object based on the best match found in a list.

I have various matching rules but have simplified this for the example:

objectImTryingToSet =
MyListOfPotentialMatches.FirstOrDefault(*/lamda checking numerous things*/) ??                  //rule1
MyListOfPotentialMatches.FirstOrDefault(*/lamda checking different numerous things*/) ??        //rule2
MyListOfPotentialMatches.FirstOrDefault(*/lamda checking again different numerous things*/);    //rule3

For debugging purposes, I would like to store a string logging which rule was the one which successfully assigned objectImTryingToSet as I have a bug wherby in one scenario the object is being assigned when it shouldn't be and its a real headache manually trying to sift through all these rules to find out where the incorrect assignment lies.

So I basically want, pseudo:

string ruleThatMatched = null;

objectImTryingToSet =
MyListOfPotentialMatches.FirstOrDefault(*/lamda checking numerous things*/) ??  if (objectImTryingToSet != null) { ruleThatMatched = "rule1" }                 //rule1
MyListOfPotentialMatches.FirstOrDefault(*/lamda checking different numerous things*/) ??  if (objectImTryingToSet != null) { ruleThatMatched = "rule2" }       //rule2
MyListOfPotentialMatches.FirstOrDefault(*/lamda checking again different numerous things*/); if (objectImTryingToSet != null) { ruleThatMatched = "rule3"}     //rule3

//tried all the rules and still no match
if (objectImTryingToSet == null)
{
    ruleThatMatched = "no rule managed to find a match";
}

Is this even possible using the ?? operator?

like image 899
JsonStatham Avatar asked Jun 19 '15 14:06

JsonStatham


1 Answers

You can do it like this:

var res =
    MyListOfPotentialMatches.Select(v => new {r=1, v}).FirstOrDefault(/*lamda checking numerous things*/) ??
    MyListOfPotentialMatches.Select(v => new {r=2, v}).FirstOrDefault(/*lamda checking different numerous things*/) ??
    MyListOfPotentialMatches.Select(v => new {r=3, v}).FirstOrDefault(/*lamda checking again different numerous things*/);
if (res != null) {
    var ruleNumber = res.r;
    objectImTryingToSet = res.v;
}

The key is Select which pairs up the result with a hard-coded rule number.

Note that you could do it without ?? operator, too:

var firstChoice = MyListOfPotentialMatches.Select(v => new {r=1, v}).Where(/*lamda checking numerous things*/);
var secondChoice = MyListOfPotentialMatches.Select(v => new {r=2, v}).Where(/*lamda checking different numerous things*/);
var thirdChoice = MyListOfPotentialMatches.Select(v => new {r=3, v}).Where(/*lamda checking again different numerous things*/);
var res = firstChoice.Concat(secondChoice).Concat(thirdChoice).FirstOrDefault();
if (res != null) {
    var ruleNumber = res.r;
    objectImTryingToSet = res.v;
}
like image 52
Sergey Kalinichenko Avatar answered Oct 26 '22 21:10

Sergey Kalinichenko