if(currency.equal("CND"))
if (string.IsNullOrEmpty(member.LastName))
{
return $"{member.FirstName}".Trim();
}
else
{
return $"{member.LastName} {member.FirstName}".Trim();
}
else
if (string.IsNullOrEmpty(member.LastName))
{
return $"{member.FirstName}".Trim();
}
else
{
return $"{member.FirstName} {member.LastName}".Trim();
}
I need to simplify this statement shorter but im not sure how? Im newbie in this stuff i might need some help on it.. any suggestion?
This does not necessarily simplifies it, it simply makes it a one-liner
return $"{(!member.LastName.IsNullOrEmpty() ? member.LastName : "")}{member.FirstName}".Trim();
However, for better clarity and readibility the if/else block is perfectly fine...
if (string.IsNullOrEmpty(member.LastName))
{
return $"{member.FirstName}".Trim();
}
else
{
return $"{member.LastName} {member.FirstName}".Trim();
}
I would definitely prefer the if...else block to using a one-line string interpolation
You can move some of your code around to cut out the duplication. If the last name is missing, the first name is the only one to print, so test for that first. Then test for the condition that prints out the full name in the preferred order.
if (string.IsNullOrEmpty(member.LastName))
{
return member.FirstName.Trim();
}
else
{
return currency.equal("CND")
? $"{member.LastName} {member.FirstName}".Trim()
: $"{member.FirstName} {member.LastName}".Trim();
}
You could rewrite it as a nested ternary operation too, though it's no shorter really and whether it's more readable depends on the person reading it...
return (string.IsNullOrEmpty(member.LastName)
? member.FirstName
: currency.equal("CND")
? $"{member.LastName} {member.FirstName}"
: $"{member.FirstName} {member.LastName}").Trim();
This is definitely over-engineered. Not shorter, but intent is clearer and it is easily extensible.
public static string GetDisplayName(Member member, string currency)
{
return string.Join(" ", GetDisplayNameParts(member, currency));
}
public static IEnumerable<string> GetDisplayNameParts(Member member, string currency)
{
switch (currency)
{
case "CND":
yield return member.LastName ?? ""
yield return member.FirstName ?? ""
yield break;
default:
yield return member.FirstName ?? ""
yield return member.LastName ?? ""
yield break;
}
}
Related
I have a method that checks multiple conditions to execute further, only to proceed to next if the current condition evaluates to false, otherwise the method will exit without evaluating further conditions. And the number of conditions vary in different implementations (subclasses).
I'm limited by my creativity to make it look any better than using the dreaded goto statement. Is there any better way to do the following:
public bool DoSomething()
{
bool result = true;
if (exclusion1)
{
result = false; goto Exit_Now;
}
if (exclusion2)
{
result = false; goto Exit_Now;
}
if (exclusion3)
{
result = false; goto Exit_Now;
}
if (exclusion4)
{
result = false; goto Exit_Now;
}
if (exclusion5)
{
result = false; goto Exit_Now;
}
if (result)
{
//do something
}
Exit_Now:
return result;
}
EDIT: In response to the answers, I understand using "else if" and conditional OR '||' operator are the obvious choices:
Subquery: which is more performant? I ask because this happens inside a loop and each evaluation takes about 30-40 ms. What is supposed to be finished in under a minute is taking up to two minutes without the goto statements in the code given above. Hence, the query. Thanks for all the help.
If you can fit your exclusion tests into the if statement, just use else if statements;
if (exclusion1)
{
result = false;
}
else if (exclusion2)
// etc ...
else if (result)
{
//do something
}
But I find it's much simpler, and easier to read, to just return early;
if (exclusion1)
return false;
One way to simplify this is to treat the exclusions as a guard clause:
public bool DoSomething()
{
if (exclusion1 ||
exclusion2 ||
exclusion3 ||
exclusion4 ||
exclusion5)
{
return false;
}
//do something
return true;
}
This also has the benefit of removing the nesting of the //do something towards the end.
you can always do this:
result = !(exclusion || exclustion2 ...|| exclusionN);
I am still learning C# but I've been on annual leave and I have come back to work and seen this piece of code my senior has left me before he went on his annual leave:
public string GetBasketTotalPrice(string basketLocation)
{
var basketTotalPrice = _driver.FindElements(CommonPageElements.BasketTotalPrice);
if (basketLocation.ToLower() == "top")
return basketTotalPrice[0].Text.Replace("£", "");
else
return basketTotalPrice[1].Text.Replace("£", "");
}
private int GetElementIndexForBasketLocation(string basketLocation)
{
return basketLocation == "top" ? 0 : 1;
}
I am assuming instead of using the if else statement, he wants me to use his new method of GetElementIndexForBasketLocation.
My question is simply how to implement this change?
Thanks
It's not totally clear what you're looking for, but you can rework the code something like this:
public string GetBasketTotalPrice(string basketLocation)
{
var basketTotalPrice = _driver.FindElements(CommonPageElements.BasketTotalPrice);
int index = GetElementIndexForBasketLocation(basketLocation);
return basketTotalPrice[index].Text.Replace("£", "");
}
private int GetElementIndexForBasketLocation(string basketLocation)
{
return basketLocation.ToLower() == "top" ? 0 : 1;
}
It looks like the method he provided you isn't calling ToLower(), leaving it to the client to do that work, which could lead to mistakes down the road.
Also, you might consider using string.Equals with StringComparison.OrdinalIgnoreCase instead of ToLower.
And it might be a good idea to add a null check before trying to call a method on the string, so you can throw an ArgumentNullException instead of the NullReferenceException that the current code will throw.
public string GetBasketTotalPrice(string basketLocation)
{
var basketTotalPrice = _driver.FindElements(CommonPageElements.BasketTotalPrice);
return basketTotalPrice[GetElementIndexForBasketLocation(basketLocation)]
.Text.Replace("£", "");
}
private int GetElementIndexForBasketLocation(string basketLocation)
{
if (basketLocation == null) throw new ArgumentNullException(nameof(basketLocation));
return basketLocation.Equals("top", StringComparison.OrdinalIgnoreCase) ? 0 : 1;
}
I have the following log file:
START:SOME_STRING
BL:2
LK:3
LH:5
end
START:SOME_STRING
BL:5
LK:6
LH:6
end
Which has multiple START: -> end structures inside. Is there a better 'non-sloppy' way of parsing this file rather than reading line by line and using SPLIT?
You can try to formalize your ini-file's grammar, and you some of parser generators. See this question for more detail.
Be aware howeveer that for such a simple grammar as yours it might be easier to parse manually :-P
class IniEntry
{
public int BL;
public int LK;
public int LH;
IniEntry Clone() { return new IniEntry { BL = BL, LK = LK, LH = LH }; }
}
IEnumerable<IniEntry> Parse()
{
IniEntry ie = new IniEntry();
while (ParseEntry(out ie))
yield return ie.Clone();
}
bool ParseEntry(out IniEntry ie)
{
ie = new IniEntry();
return ParseStart(ie) &&
ParseBL(ie) &&
ParseLK(ie) &&
ParseLH(ie) &&
ParseEnd(ie);
}
bool ParseStart(IniEntry ie)
{
string dummy;
return ParseLine("START", out dummy);
}
bool ParseBL(IniEntry ie)
{
string BL;
return ParseLine("BL", out BL) && int.TryParse(BL, out ie.BL);
}
bool ParseLK(IniEntry ie)
{
string LK;
return ParseLine("LK", out LK) && int.TryParse(LK, out ie.LK);
}
bool ParseLH(IniEntry ie)
{
string LH;
return ParseLine("LH", out LH) && string.TryParse(LH, out ie.LH);
}
bool ParseLine(string key, out string value)
{
string line = GetNextLine();
var parts = line.Split(":");
if (parts.Count != 2) return false;
if (parts[0] != key) return false;
value = parts[1];
}
etc.
This is a good candidate for a while loop and a state machine.
With this approach you would use even use less memory and have greater performance than using string.split()
If it is certain that the START/END are always matched, (apologies, my C# is embarrassing, so plain English):
Read the whole file with System.IO.ReadToEnd
Parse the whole thing in one go with a regular expression
Iterate over regex results
The regex would be something like "(START:([^$]+)$BL:([^$]+)$LK:([^$]+)$LH:([^$]+)$end$)+", off the top of my head, you'll need to validate/adjust according to how your parameters BL/LK etc. occur
What is difference between these two examples:
if(firstchek)
{
if(second)
{
return here();
}
else
{
return here();
}
}
and this:
if(firstcheck)
{
if(second)
{
return here();
}
return here();
// else code without else
}
// code without else
// else code is here
return here();
This code:
if (someCondition)
{
foo();
return;
}
bar();
return;
is the same as this:
if (someCondition)
{
foo();
}
else
{
bar();
}
return;
The only difference is in readability. Sometimes one way is more readable, sometimes the other. See Refactoring: Replace Nested Conditional with Guard Clauses.
Nested conditionals:
double getPayAmount() {
double result;
if (_isDead) result = deadAmount();
else {
if (_isSeparated) result = separatedAmount();
else {
if (_isRetired) result = retiredAmount();
else result = normalPayAmount();
};
}
return result;
};
Guard clauses:
double getPayAmount() {
if (_isDead) return deadAmount();
if (_isSeparated) return separatedAmount();
if (_isRetired) return retiredAmount();
return normalPayAmount();
};
Assuming there is no other code, there is no difference in terms of code paths and what gets executed.
The main difference, in general, is that when specifying an else clause, this will only run if the expression in the if evaluates to false. If you do not specify it, the code will always run.
Update:
This:
if(second)
{
return here();
}
else
{
return here();
}
And this:
if(second)
{
return here();
}
return here();
Would be the same as this:
return here();
Why? Because you are doing the same thing regardless of what second evaluates to, so the check is superfluous.
The two sets of code are semantically similar. That is to say they will perform the same at run time. However, Whether you should use one form or another depends on the situation. Your code should express your intent in addition to the required semantics.
If the intent of the code is to do one or the other then keep the else so your intent is explicit. E.g.
if (withdrawAmmount < accountBalance)
{
return Deduct();
}
else
{
return ArrangeCredit();
}
If however the intent is to do the first thing in a special case then feel free to omit the else. E.g.
if (parameter == null)
{
return NothingToDo();
}
return PerformActions();
For maintainability you should consider whether removing the return statements will change the behaviour and code on the basis that some idiot will do that (it could be me).
It should also be noted that with the else the code performs the same without the returns but without the returns omitting the else will cause the code to behave differently.
With the first code you are running something regardless if second is a defined value or not. It just depends on whether it is a defined value or not. If it is you run one bit of code. If it isn't then you run another. With the second example you will only run code if second is a defined value.
In the first case, the else part is only executed if the second variable is false.
In the second case, the part where the else is left out is always executed (given that firstcheck is true in both cases).
Your code has too many return statements that i feel as repetitive for example
if(firstchek)
{
if(second)
{
return here();
}
else
{
return here();
}
}
the above is equal to
if(firstchek)
{
return here();
}
because here() is the same function call. And the second example
if(firstcheck)
{
if(second)
{
return here();
}
return here();
// else code without else
}
// code without else
// else code is here
return here();
is equal to
if(firstcheck)
{
return here();
}
return here();
In the first example if there are some statement after the example and the top level if condition fails then the statements following it will be executed example
if(firstchek)
{
if(second)
{
return here();
}
else
{
return here();
}
}
CallMyCellNo();
CallMyCellNo() will be called if the toplevel if condition fails.
In the second example you have return here() after the toplevel if statement so regardless of the if condition's return value the function execution will terminate.
I came across the following expression in someone else's code. I think it's terrible code for a number of reasons (not least because it fails to take into account bool.TrueString and bool.FalseString), but am curious as to how the compiler will evaluate it.
private bool GetBoolValue(string value)
{
return value != null ? value.ToUpper() == "ON" ? true : false : false;
}
Edit
Incidentally, aren't the expressions evaluated from the inside-outwards? In this case, what's the point of checking for value != null after the call to value.ToUpper() which will throw a null reference exception?
I think the following is a correct (deliberately) verbose version (I'd never leave it like this :D ):
if (value != null)
{
if (value.ToUpper() == "ON")
{
return true;
}
else // this else is actually pointless
{
return false;
}
}
else
{
return false;
}
Which can be shortened to:
return value != null && value.ToUpper == "ON";
Is this a correct re-writing of the expression?
It looks like the method is indended to handle a value that comes from a checkbox HTML element. If no value is specified for the checkbox, it uses the value "on" by default. If the checkbox is not checked there is no value at all from it in the form data, so reading the key from Request.Form gives a null reference.
In this context the method is correct, althought it's quite horrible due to the use of the if-condition-then-true-else-false anti-pattern. Also it should have been given a name that is more fitting for it's specific use, like GetCheckboxValue.
Your rewrite of the method is correct and sound. As the value is not culture dependant, converting the value to uppercase should not use the current culture. So a rewrite that is even slightly better than the one that you proposed would be:
return value != null && value.ToUpperInvariant == "ON";
(The culture independent methods are also a bit faster than the ones using a specific culture, so there is no reason not to use them.)
Incidentally, aren't the expressions
evaluated from the inside-outwards?
If it was method calls so that all expressions were actually evaluated, they would, as the inner call has to be made to evaluate the parameters for the outer call.
However, the second and third operands of the conditional expression is only evaluated if they are used, so the expressions are evaluated from the outside and inwards. The outermost condition is evaluated first to decide which of the operands it will evaluate.
You are correct, both in your rewriting and in your assertion that this attempt at conciseness is bad because it leads to confusion.
well the first one is a double-nested ternary operator
return (value != null) ? [[[value.ToUpper() == "ON" ? true : false]]] : false;
The bit in [[[ ]]] is the first result of the ternary expression which gets evaluated
when the first condition is true so you're reading/assertion of it is correct
but its ugly as hell and very unreadable/unmaintainable in its current state.
I'd definitely change it to your last suggestion
SideNote:
People who do
if(X == true)
return true;
else
return false;
instead of
return X;
should be taken out and shot ;-)
Are you looking for speed or readability and organization? Speed of execution, your shortened example is probably the best way to go.
For a few extra milliseconds, you could re-write this utility method as an extension method like so:
public static bool ToBoolean(this string value)
{
// Exit now if no value is set
if (string.IsNullOrEmpty(value)) return false;
switch (value.ToUpperInvariant())
{
case "ON":
case "TRUE":
return true;
}
return false;
}
... and then you would use it as follows:
public static void TestMethod()
{
bool s = "Test".ToBoolean();
}
EDIT:
Actually, I'm wrong... a quick performance test shows that the extension method is FASTER than the inline method. The source of my test is below, as well as the output on my PC.
[Test]
public void Perf()
{
var testValues = new string[] {"true", "On", "test", "FaLsE", "Bogus", ""};
var rdm = new Random();
int RunCount = 100000;
bool b;
string s;
Stopwatch sw = Stopwatch.StartNew();
for (var i=0; i<RunCount; i++)
{
s = testValues[rdm.Next(0, testValues.Length - 1)];
b = s.ToBoolean();
}
Console.Out.WriteLine("Method 1: {0}ms", sw.ElapsedMilliseconds);
sw = Stopwatch.StartNew();
for (var i = 0; i < RunCount; i++)
{
s = testValues[rdm.Next(0, testValues.Length - 1)];
b = s != null ? s.ToUpperInvariant() == "ON" ? true : s.ToUpperInvariant() == "TRUE" ? true : false : false;
}
Console.Out.WriteLine("Method 2: {0}ms", sw.ElapsedMilliseconds);
}
Output:
Method 1: 21ms
Method 2: 30ms
I read the original expression the same way you do. So I think your shortened expression is correct. If value is null it will never get to the second conditional, so it looks safe to me.
I also hate the constructs like:
if (value.ToUpper() == "ON")
{
return true;
}
else // this else is actually pointless
{
return false;
}
as you noticed it is a long and convoluted (not to say stupid) way of writing:
return value.ToUpper() == "ON";
Your proposition is nice, short and correct.
Another alternative:
return string.Equals( value, "ON", StringComparison.OrdinalIgnoreCase );