c# two nested if statements, one else - c#

Please excuse the question that seems simple, but for some reason I cannot think of an elegant solution at the moment.
I have the following situation:
if (Request.QueryString["name"] != null)
{
if (Request.QueryString["name"].ToString() != "")
{
nameSpan.InnerHtml = Request.QueryString["name"].ToString();
}
}
The problem is, if I want to hide the nameSpan if querystring["name"] is either null or emtpy. The ugly solution would be:
if (Request.QueryString["name"] != null)
{
if (Request.QueryString["name"].ToString() != "")
{
nameSpan.InnerHtml = Request.QueryString["name"].ToString();
}
else
{
nameSpan.Visible = false;
}
}
else
{
nameSpan.Visible = false;
}
I would like to have a situation where both the nameSpan.Visible = false; sections could be merged into one area so I only have to write it once.
As far as I am aware, it is not possible to do the following:
if (Request.QueryString["name"] != null && Request.QueryString["name"].ToString() != "")
{
nameSpan.InnerHtml = Request.QueryString["name"].ToString();
}
else
{
nameSpan.Visible = false;
}
But please tell me if I am wrong! If you have a different solution which changes the logic then I am more than happy to have different views! Thank you!

Your && solution should be fine. If left side of && is false, right side it not evaluated so there will be no exception.
If you want, you could use String.IsNullOrEmpty static method:
if (!string.IsNullOrEmpty(Request.QueryString["name"]))
{
nameSpan.InnerHtml = Request.QueryString["name"].ToString();
}
else
{
nameSpan.Visible = false;
}

if you are after compact code, I'd use next (NameValueCollection returns null if key does not exist, and indexer returns string):
nameSpan.InnerHtml = Request.QueryString["name"];
nameSpan.Visible = !string.IsNullOrEmpty(nameSpan.InnerHtml);

Related

I get a wrong resultset of a List<> when using Linq's Where with lambda

I am programming a simulation thingy that I can use as a basis for a game or something later. I am programming in C# and with Unity. Unity is up to date on version 2017.1.0f3 (or 3.3.0.2 ?).
The simulation just spawns some random people and when they get older they may search for a partner and reproduce themselves.
Now I have some weird behaviour in that "search for a partner"-method. I will show the code below in a second. The method takes a list of people as an argument and validates that list to filter out every person that is older than 15 years and don't have a partner already. Also related persons get filtered out because I don't really want incest inside my simulation .. (yet? ^^)
To clarify my problem: in the List<> called potentialPartners are somehow people already having a partner. I am sure that it is no multithreading-caused problem because those partners were not set in the same frame. Also I by myself don't do any multithreading stuff yet, there're just the threads Unity creates as default.
public void SearchForPartner(List<PawnLogic> pawnsInRange)
{
if (!this.PartnerAllowed)
return;
System.Random rnd = new System.Random();
List<PawnLogic> potentialPartners = new List<PawnLogic>();
var pP = pawnsInRange.Where(x => x.PartnerAllowed && x.Gender != this.Gender && !this.IsKindred(x) && !x.IsKindred(this));
if (pP.Count() > 0)
potentialPartners.AddRange(pP);
if (potentialPartners.Count == 0)
return;
this.Partner = potentialPartners[rnd.Next(0, potentialPartners.Count)];
if (this.Partner.IsAlive)
{
this.Partner.Partner = this;
if (this.News != null)
{
this.News.Invoke(this, new NewsEventArgs(this, this.FirstLastName + " and " + this.Partner.FirstLastName + " become a couple."));
}
if (Gender == 'M')
this.Partner.SetNewLastname(this.thisPawn.LastnameNumber);
else
this.SetNewLastname(Partner.thisPawn.LastnameNumber);
}
else
this.Partner = null;
}
I guess my problem comes from the property "PartnerAllowed" because if I remember correctly the &&-operator only validates the right hand side if the left hand side returns true.
public bool PartnerAllowed
{
get
{
return this.partner == null && this.Age >= 16;
}
}
Just to be complete here is the IsKindred-method.. I don't really think that my problem comes outside of this but maybe I am not seeing something important.
public bool IsKindred(PawnLogic check)
{
if (Generation <= check.Generation - 4)
return false;
if ((Father == null || Mother == null || check.Father == null || check.Mother == null) && Siblings.Count == 0)
return false;
if (check == Mother || check == Father)
return true;
if (Siblings.Contains(check))
return true;
for (int i = 0; i < Siblings.Count; i++)
{
if (Siblings[i].Children.Contains(check))
return true;
}
if (Father != null && Father.IsKindred(check))
return true;
if (Mother != null && Mother.IsKindred(check))
return true;
return false;
}
My Partner-property looks like this:
public PawnLogic Partner
{
get
{
if (this.partner == null && this.thisPawn.PartnerNumber != null)
{
int indexOfPartner = this.thisPawn.PartnerNumber.ToInt();
if (indexOfPartner != -1)
this.partner = new PawnLogic(indexOfPartner);
else
this.partner = null;
}
return this.partner;
}
private set
{
if (value == null)
this.thisPawn.PartnerNumber = null;
else
{
this.thisPawn.PartnerNumber = value.Number;
this.partner = value;
}
}
}
I have no idea how to fix this. Especially because it works in another program which I wrote first. But I needed to transfer the code to this new project because Unity doesn't use .Net 4.6 yet. Maybe there was a change in Linq's behaviour between the framework-versions? Do someone can help me?
It is just a private project, but I want it to work properly anyway. :P
Let me know if you need more code or explanation to understand what is happening, what is supposed to happen or how something works.
Thank you for your time and effort :)

Evaluating boolean expression in C#

I have written the code below to evaluate a boolean expression. The expression is coded in the form of objects.
It's one of those moments when I look at the code and think: I'm sure there's a better way to code that, using less boolean variables but can't see the right way to go. Any help? Unit tests have been written and are passing for a variety of inputs.
if (tree == null || !tree.IsActive || tree.FilterNodes == null)
{
return false;
}
var result = false;
foreach (var filter in tree.FilterNodes.Where(a => a.IsActive && a.ConditionNodes != null))
{
var tempBool = false;
foreach (var condition in filter.ConditionNodes.Where(a => a.IsActive))
{
if (!string.IsNullOrWhiteSpace(condition.FieldName) && values.ContainsKey(condition.FieldName))
{
var value = values[condition.FieldName];
if (filter.LogicalOperator == LogicalOperator.Or && ApplyCondition(condition.ConditionOperator, value, condition.FieldValue))
{
tempBool = true;
break;
}
else if (filter.LogicalOperator == LogicalOperator.And)
{
tempBool = ApplyCondition(condition.ConditionOperator, value, condition.FieldValue);
if (!tempBool)
{
break;
}
}
else
{
tempBool = false;
}
}
else if (!string.IsNullOrWhiteSpace(condition.FieldName) && filter.LogicalOperator == LogicalOperator.And)
{
tempBool = false;
}
}
result = tempBool;
if (!result)
{
break;
}
}
return result;
You could set tempBool = false first thing in the loop and leave out the else and last else if:
foreach (var condition in filter.ConditionNodes.Where(a => a.IsActive))
{
tempBool = false;
if (!string.IsNullOrWhiteSpace(condition.FieldName) && values.ContainsKey(condition.FieldName))
{
var value = values[condition.FieldName];
if (filter.LogicalOperator == LogicalOperator.Or && ApplyCondition(condition.ConditionOperator, value, condition.FieldValue))
{
tempBool = true;
break;
}
else if (filter.LogicalOperator == LogicalOperator.And)
{
tempBool = ApplyCondition(condition.ConditionOperator, value, condition.FieldValue);
if (!tempBool)
{
break;
}
}
}
}
EDIT
It gets even simpler:
foreach (var condition in filter.ConditionNodes.Where(a => a.IsActive))
{
tempBool = false;
if (!string.IsNullOrWhiteSpace(condition.FieldName) && values.ContainsKey(condition.FieldName))
{
var value = values[condition.FieldName];
tempBool == ApplyCondition(condition.ConditionOperator, value, condition.FieldValue);
if ((filter.LogicalOperator == LogicalOperator.And && !tempBool) || (filter.LogicalOperator == LogicalOperator.Or && tempBool))
{
break;
}
}
}
In the if you need ApplyCondition to be true and then set tempBool to true (also the result of ApplyCondition). In the else if you set tempBoolto the result of ApplyCondition. That means you can set tempBoolto the result of ApplyConditionin the first place. Now you just need to decide if you need to break.
Taking a more o-o approach, I think your operators need to be defined by classes that inherit from a base class. The base class would have an abstract Evaluate method that your operators implement. You can then use o-o polymorphism to evaluate your operators without worrying about the internal details. Effectively you have the beginnings of a simple interpreter.
A more formal way to code a boolean interpreter is considering a boolean expression as generated by a formal grammar and writing a parser and an interpreter for it. The interpreter could be implemented as an abstract syntax tree.
I made an open source library to achieve this, if you want you can take a look on GitHub.

Check if an array contains an invalid value and return false?

This is probably very simple but I guess I haven't had enough of coffee yet.
I have an array with four values and I want to check if any of them is invalid and then set a boolean value to false, else to true.
bool validDecoding = false;
foreach (string decodedValue in arrayOfvalues)
{
if (decodedValue.Contains("invalid") || decodedValue.Contains("length") || decodedValue.Contains("bad"))
{
validDecoding = false;
}
else
{
validDecoding = true;
}
}
But if the last does not contain invalid, length or bad then validDecoding is set to true but I want it to be false if one or more values are invalid.
Please help?
Thanks in advance.
Include System.Linq namespace and you can do following:
validDecoding = !arrayOfvalues.Any(
value => value.Contains("invalid") || value.Contains("length") || value.Contains("bad"));
bool validDecoding = false;
foreach (string decodedValue in arrayOfvalues)
{
if (!decodedValue.Contains("invalid") && !decodedValue.Contains("length") && !decodedValue.Contains("bad"))
{
validDecoding = true;
break;
}
}
Set valid to true at first, then set it to false in your loop if it's invalid.
bool validDecoding = true;
foreach (string decodedValue in arrayOfvalues)
{
if (decodedValue.Contains("invalid") || decodedValue.Contains("length") || decodedValue.Contains("bad"))
{
validDecoding = false;
break;
}
}
That way it's never set back to true! (you need more coffee ;-) )
Set your validDecoding to 'true' initially, and only reset to false if it breaks.
bool validDecoding = true;
foreach (string decodedValue in arrayOfvalues)
{
if (decodedValue.Contains("invalid") || decodedValue.Contains("length") || decodedValue.Contains("bad"))
{
validDecoding = false;
}
else
{
//Do Nothing
}
}
I like Andrew's answer. If you don't have Linq available, try this option:
// Note: Name boolean variables like they are a question
bool isValidDecoding = true;
foreach (string decodedValue in arrayOfvalues)
{
isValidDecoding &= !decodedValue.Contains("invalid")
&& !decodedValue.Contains("length")
&& !decodedValue.Contains("bad");
}
I particularly like this option when your tests contain logging, and you want to find all failures before termination.
I'd be wary of decodedValue.Contains("length") though. Maybe it works in your scenario, but it might give false negatives for other cases, and definitely makes your code less clear. You should double check that there isn't a more unique/indicative value that ensures that you have a bad decoding for those cases.

Need to check for null on something that throws exception

_sponsorOrBankFacingBorrowerCompanyWizardData = CompanyData.GetCompanyWizardData(SponsorOrBankFacingBorrowerCompany.CompanyID);
So the problem here is that the code tries to go into this statement no matter what, I want it to only go if it CAN go, obviously.
However, if I perform a watch in Visual Studio 2010 ONLY on this object SponsorOrBankFacingBorrowerCompany, no properties, methods, anything, I get a null reference exception.
How do I check for null when I get an exception before the check even happens?
Here's the watch:
EDIT:
public STPProject STPData
{
get { return _STPData; }
set
{
_STPData = value;
//set WebIds
foreach (STPCompany comp in _STPData.STPCompanyCollection)
{
comp.WebId = comp.WebId < 1 ? GetNextWebId() : comp.WebId;
foreach (STPContact cont in comp.STPContactCollection)
{
cont.WebId = cont.WebId < 1 ? GetNextWebId() : cont.WebId;
}
}
//must be before AttachSTPEvents
_STPData.AffiliateTradeIndicator = _STPData.AffiliateTradeIndicator.HasValue ? _STPData.AffiliateTradeIndicator.Value : false;
//set company wizard defaults
_sponsorOrBankFacingBorrowerCompanyWizardData = CompanyData.GetCompanyWizardData(SponsorOrBankFacingBorrowerCompany.CompanyID);
AttachSTPEvents(_STPData);
}
}
Getter for other that is throwing exception:
public STPCompany SponsorOrBankFacingBorrowerCompany
{
get
{
if (STPData.AffiliateTradeIndicator.Value)
{
return BankFacingBorrower;
}
else
{
return Sponsor;
}
}
}
Something like the following, unless I'm mistaking your question:
if (SponsorOrBankFacingBorrowerCompany != null)
{
_sponsorOrBankFacingBorrowerCompanyWizardData =
CompanyData.GetCompanyWizardData(
SponsorOrBankFacingBorrowerCompany.CompanyID);
}
Update:
Okay, this is elaborate but will hopefully make the problem become immediately evident, so let's drill this down, the long way; can you amend your property code to look like the following:
public STPCompany SponsorOrBankFacingBorrowerCompany
{
get
{
if (STPData == null)
{
throw new InvalidOperationException("'STPData' is null");
}
if (STPData.AffiliateTradeIndicator == null)
{
throw new InvalidOperationException(
"'STPData.AffiliateTradeIndicator' is null");
}
if (STPData.AffiliateTradeIndicator.Value == null)
{
throw new InvalidOperationException(
"'STPData.AffiliateTradeIndicator.Value' is null"); ;
}
if (STPData.AffiliateTradeIndicator.Value)
{
return BankFacingBorrower;
}
else
{
return Sponsor;
}
}
}
I'm betting you're getting a null reference from your SponsorOrBankFacingBorrowerCompany getter in here:
STPData.AffiliateTradeIndicator.Value
Check all those parts in the debugger...

Error when assigning a boolean value

I am getting an error while assigning a value.
My code is:
protected bool ValidateProfile()
{
bool blnFirstName = false;
bool blnLastName = false;
bool blnEMail = false;
//(error on line below: "The left-hand side of an assignment must be a variable, property or indexer")
ValidateProfile() = false;
if txtFName != ""
blnFName = true;
if txtLName != ""
blnLName = true;
if txtEMail != ""
blnEMail = true;
if (blnFName) && (blnLName) && (blnEMail))
ValidateProfile = true;
}
How do I assign a boolean value to ValidateProfile ?
Thanks
You want
return false;
In C#, we don't assign values to the function name in order to return a value.
If you want to set the return value at a different point in time from when you return from the method, then you should do something like this:
bool retVal; // Defaults to false
if (condition)
retVal = true;
if (otherCondition)
retVal = false;
if (thirdCondition)
retVal = true;
return retVal;
You can't assign a value to a function. You need return false;
As others have pointed out, in C# you use return instead of MyFunction = x. In this scenario, you can assign the result of your final check to a boolean and return it:
bool retVal = (blnFName) && (blnLName) && (blnEMail);
return retVal;
Alternatively, you could just skip the assignment altogether:
return (blnFName) && (blnLName) && (blnEMail);
EDIT: I noticed you are using hungarian notation, which implies that txtFName is a TextBox. Keep in mind that C# doesn't have default properties like VB. If it is a TextBox, it will never equal "", because it's not of type System.String. I'm guessing you actually wanting to evaluate txtFName.Text
Change that last line to:
return false;
Although it seems you're always returning false here. Is there an option to return true?
Just a side note besides all the returns...
You may want to change this:
if txtFName != ""
To check if the String.IsEmptyOrNull(txtFName.Text)
Or at least initialize your variables to either null or String.Empty.
Just an FYI though.
You want to return false
Alright, taking the code you posted:
protected bool ValidateProfile()
{
return !String.IsNullOrEmpty(txtFName) && !String.IsNullOrEmpty(txtLName) && !String.IsNullOrEmpty(txtEMail);
}
Or
protected bool ValidateProfile()
{
bool returnValue = true;
if(String.IsNullOrEmpty(txtFName))
{
returnValue=false;
}
else if(String.IsNullOrEmpty(txtLName))
{
returnValue = false;
}
else if(String.IsNullOrEmpty(txtEMail))
{
returnValue = false;
}
return returnValue;
}
Though you could just return false as soon as you find an invalid field.
Not a C# programmer, but can't you just write:
return (txtFName != "") && (txtLName != "") && (txtEMail != "");
for the body of the function?

Categories

Resources