C# - Shorter version of IF statement
Is there a shorter version of IF statement to do this?
if (el.type == ElementType.Type1 || el.type == ElementType.开发者_运维百科Type2)
You could use an extension method, but would this really be much better?
Throw this on a static class:
public static bool IsOneOf(this ElementType self, params ElementType[] options)
{
return options.Contains(self);
}
And then you can do:
if (el.type.IsOneOf(ElementType.Type1, ElementType.Type2)) {
However, this will be a lot slower than your if statement, as there is an implicit array initialization followed by an array traversal, as opposed to (at the most) two compares and branches.
Consider ElementType is defined as
enum ElementType
{
Type1,
Type2,
Type3
}
In this particular case you may write if(el.type<ElementType3)
By default Type1 equals to 0, Type2 equals 1, etc
If you have only 2 values, I strongly suggest to use the code you posted, because is likely the most readable, elegant and fast code possible (IMHO).
But if you have more cases like that and more complicated, you could think to use a switch
statement:
switch (el.type)
{
case ElementType.Type1:
case ElementType.Type2:
case ElementType.Type3:
//code here
break;
case ElementType.Type4:
case ElementType.Type5:
//code here
break;
case ElementType.Type6:
//code here
break;
}
that translated in if statements
would be:
if (el.type == ElementType.Type1 ||
el.type == ElementType.Type2 ||
el.type == ElementType.Type3 )
{
// code here
}else if(el.type == ElementType.Type4 ||
el.type == ElementType.Type5)
{
// code here
}else if(el.type == ElementType.Type6)
{
// code here
}
They're perfectly equal to me, but the switch
seems more readable/clearer, and you need to type less (i.e. it's "shorter" in term of code length) :)
You can try this:
if(new [] { ElementType.Type1, ElementType.Type2 }.Contains(el.type))
(turns out, that takes even more characters)
I guess you're referring to an IN() clause or some such? Not really... Well, sort of... You can do something like:
if ((new [] { ElementType.Type1, ElementType.Type2}).Contains(el.type)) {...}
But that's not going to be anywhere near as performant (or brief) as what you're already doing. You can also do
if (el.type == ElementType.Type1 | el.type == ElementType.Type2)
but that doesn't do short-circuit evaluation, so you rarely want to use that operator. My advice is to stick with what you have.
The brief answer is no. There isn't C# language construct that lets you combine object comparisons. But as many people have mentioned before, creating a collection of your types is probably your best bet in creating a shorter if statement. However that sacrifices quite a bit in the area of performance. I would stick with the OR statement.
There is no better way to optimize your code. As other users have shown, you can optimize an if else.
But a type of if statement I have thought about, in your case especially, would be
if(X > [Y || Z || A])
But that doesn't exist, and isn't as clean as the current if (X > Y || X > Z || X > A)
(This is more of a response to Cody Gray)
If this is a common logic comparison in your code that shows up alot I'd just write a method to handle it.
private bool isType1OrType2(ElementType type)
{
return type == ElementType.Type1 || type == ElementType.Type2;
}
then you can do
if(isType1OrType2(el.type))
You could also make this an extension method like so
public static bool isType1OrType2(this ElementType type)
{
return type == ElementType.Type1 || type == ElementType.Type2;
}
so the code would read a little nicer
if(el.type.isType1OrType2())
But then you have to have a static class but you can decide if it's worth it. I personally would not write a method to take a collection of types to compare to unless you find that you are comparing the type to many different combinations. I also would not even bother changing the code at all if this is the only place you make this type of comparison.
i dont think there is a way to optimize your statement
In short: nothing reasonable (reasonable in terms of code readability and performance optimisation). I wouldn't recommend the ternary operator for this kind of comparison either.
The actual if can be shortened to 5 characters ;)
bool b = (el.type == ElementType.Type1) | (el.type == ElementType.Type2);
if(b){...}
Don't do this, it is stupid and confusing unless you have a finite-state automaton.
enum MyEnum
{
A,
B,
C
}
private readonly Dictionary<MyEnum, Action> _handlers = new Dictionary<MyEnum, Action>
{
{MyEnum.A,()=>Console.Out.WriteLine("Foo")},
{MyEnum.B,()=>Console.Out.WriteLine("Bar")},
};
public static void ActOn(MyEnum e)
{
Action handler = null;
if (_handlers.TryGetValue(e, out handler) && handler != null)
{
handler();
}
}
Another approach would be to do some bitwise comparison, but really not worth it again.
private void ActWithCast(MyEnum e)
{
const int interest = (int)MyEnum.A | (int)MyEnum.B;
if (0 != ((int)e & interest))
{
Console.Out.WriteLine("Blam");
}
}
If the ElementType is an enum there is a shorter way to do it:
[Flags]
public enum ElementType
{
Type1 = 1,
Type2 = 2,
Type3 = 4,
}
...
tElementType.HasFlag(ElementType.Type1 | ElementType.Type2);
You do not need the [Flags] attribute to use HasFlag, but the values of each of them do need to follow that pattern.
精彩评论