if condition, multiple options

  • (2 Pages)
  • +
  • 1
  • 2

22 Replies - 2458 Views - Last Post: 02 March 2016 - 08:07 AM

#16 Curtis Rutland  Icon User is offline

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 5101
  • View blog
  • Posts: 9,283
  • Joined: 08-June 10

Re: if condition, multiple options

Posted 22 December 2015 - 12:35 PM

So, here's my original idea re-written, inspired by baavgai:

void Main()
{
	var p01 = 1.EqualsAny(1, 2, 3, 4, 5);
	var p02 = "test".EqualsAny("A", "B", "C");
	var p03 = "test".EqualsAny("A", "B", "C", "TEST");
	var p04 = "test".EqualsAny(StringComparer.CurrentCultureIgnoreCase, "A", "B", "C", "TEST");
	$"1.EqualsAny(1, 2, 3, 4, 5): {p01}".WriteLine();
	$"\"test\".EqualsAny(\"A\", \"B\", \"C\"): {p02}".WriteLine();
	$"\"test\".EqualsAny(\"A\", \"B\", \"C\", \"TEST\"): {p03}".WriteLine();
	$"\"test\".EqualsAny(StringComparer.CurrentCultureIgnoreCase, \"A\", \"B\", \"C\", \"TEST\"): {p04}".WriteLine();
}

// Define other methods and classes here
public static class Extensions
{
	public static bool EqualsAny<T>(this T item, params T[] values)
	{
		return values.Contains(item);
	}

	public static bool EqualsAny<T>(this T item, IEqualityComparer<T> comparer, params T[] values)
	{
		return values.Contains(item, comparer);
	}

	public static void WriteLine(this string s)
	{
		Console.WriteLine(s);
	}
}




Output:

Quote

1.EqualsAny(1, 2, 3, 4, 5): True
"test".EqualsAny("A", "B", "C"): False
"test".EqualsAny("A", "B", "C", "TEST"): False
"test".EqualsAny(StringComparer.CurrentCultureIgnoreCase, "A", "B", "C", "TEST"): True


I like the name "EqualsAny" better than "Equals", since it's a bit more explicit. Since default parameters and params arrays don't go well together, I made two overloads that let you provide an IEqualityComparer, which I find more and more important to do case-insensitive comparisons. I also threw in an extension method that "pivots" WriteLine, just for the hell of it.

By the way, I do this in LINQPad, if anyone else is interested. No reason to spin up an entire project. And it has IntelliSense, unlike the new C# Interactive (which is great that it finally came, but LINQPad might be a better tool for C# scripting).
Was This Post Helpful? 0
  • +
  • -

#17 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 5928
  • View blog
  • Posts: 20,267
  • Joined: 05-May 12

Re: if condition, multiple options

Posted 22 December 2015 - 05:38 PM

Maybe I'm misting the point of having the list of values all on one line. So each time you add or remove an item, when you look at the diffs, you will have to look very closely to find out what changed. Compare that to the switch statement where the typical style is to have each value on its own line. The diffs are easier to look at.

Or is this another case of many years of experience tends to prefer features that ease maintenance instead of writing the code?
Was This Post Helpful? 0
  • +
  • -

#18 xnn  Icon User is offline

  • D.I.C Head

Reputation: 37
  • View blog
  • Posts: 238
  • Joined: 10-February 10

Re: if condition, multiple options

Posted 01 March 2016 - 08:04 AM

View PostSkydiver, on 20 December 2015 - 07:30 PM, said:

Some C/C++ programmers style guides actually recommend Yoda conditions because it will cause a compilation error even if your warnings accidentally get turned off, as well as help the compiler optimize things.

This article argues that Yoda conditions are not necessary in C#.



We've used Yoda conditions in C# when comparing strings to avoid having to check for nulls with something like:

  "C".Equals(OrderStatus);


Was This Post Helpful? 0
  • +
  • -

#19 Curtis Rutland  Icon User is offline

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 5101
  • View blog
  • Posts: 9,283
  • Joined: 08-June 10

Re: if condition, multiple options

Posted 01 March 2016 - 09:08 AM

That's pretty unnecessary. C# isn't Java, you don't have to use .Equals if you're not passing in a particular comparison operator. OrderStatus == "C" will work, regardless of if OrderStatus is null or not.

Also, now we have an even better way of dealing with this:

string x = null;
var testResult = x?.Equals("Some Value") ?? false;
//testResult now equals false


The ?. operator is new to C# 6. It's called the "safe access" operator (or the "null-propagating operator"). The idea is, that if evaluating the expression on the right-hand side of the operator is null, the expression parsing stops and results in a null result.

So, given the expression var x = a.b.c.d(), if b were null, the expression would trigger a NullReferenceException. But if we re-write it as: var x = a?.b?.c?.d() (and assume b is still null), x is now null. It's type is a Nullable<T>, T being whatever the type d() should return.

Combine that with the "null coalescing operator" (the ?? operator) and you have a very useful pattern. ?? allows you to define a "default value" to be used in place of null.

So, in the expression var result = x?.Equals("test") ?? false;, if x is null, the whole expression is null. Then the ?? operator says "since it's null, replace it's value with false". So, result is false.
Was This Post Helpful? 0
  • +
  • -

#20 xnn  Icon User is offline

  • D.I.C Head

Reputation: 37
  • View blog
  • Posts: 238
  • Joined: 10-February 10

Re: if condition, multiple options

Posted 01 March 2016 - 03:34 PM

I oversimplified my example. We used the overload of the equals method where you'd specify the StringComparison type for case/culture (in)sensitivity.
Was This Post Helpful? 0
  • +
  • -

#21 Curtis Rutland  Icon User is offline

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 5101
  • View blog
  • Posts: 9,283
  • Joined: 08-June 10

Re: if condition, multiple options

Posted 01 March 2016 - 04:43 PM

Which is why my reply included everything past the first paragraph.
Was This Post Helpful? 0
  • +
  • -

#22 xnn  Icon User is offline

  • D.I.C Head

Reputation: 37
  • View blog
  • Posts: 238
  • Joined: 10-February 10

Re: if condition, multiple options

Posted 02 March 2016 - 07:11 AM

Yes null propagator operators do solve this issue as you stated.

I've seen a lot of discussion online about people not very eager to utilize this new language feature. A lot of people say it hurts readability/maintainability. I don't mind it because I'm not a big fan of heavily nested if statements when null checking. What are your thoughts on its readability and have you seen medium to large teams adopt it's usage?
Was This Post Helpful? 0
  • +
  • -

#23 Curtis Rutland  Icon User is offline

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 5101
  • View blog
  • Posts: 9,283
  • Joined: 08-June 10

Re: if condition, multiple options

Posted 02 March 2016 - 08:07 AM

I've been on the same team since it was released, so I can't speak for others. But my team uses it. We're not a big team (more like a collective of individuals working on several discrete projects), but we're pretty focused on new technology. We embraced most of the new C# features (expression body syntax is great by the way).

My feelings on the feature itself: I would have loved it many years ago. But having gone so long without it, I find that my style just works around the lack. I don't find myself doing a lot of chained calls, because they were dangerous in the past without lots of null checking. So, I don't find the necessity to use them very often.

But I don't believe it harms readability. I believe that people who say it does are the people who don't want to put the time in to learn modern-style programming. Once you've been programming for a long enough time (and seen styles come and go), you can start to tell when people stopped learning just by reading the code they write. I know people that complain that Lambdas are unreadable. Well, I guess they are, if you haven't bothered to learn anything about them in the many years they've been part of the language. This feature is no more or less readable, if you know what the operator means.

And IMO, this:

if(a != null && a.b != null && a.b.c != null){
  var result = a.b.c.d();
  if(result != null) {
    //do something
  }
}


is less readable than this:

if(a?.b?.c?.d() ?? false) {
  //do something
}


Assuming you know what those two operators do, it's actually more readable.
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2