C# Determine which condition was satisfied - c#

In my C# code I'm having the following code:
if (A == null)
{
errors.Add(nameof(A), "A does not exist.");
return Task.CompletedTask;
}
else if (B == null)
{
errors.Add(nameof(B), "B does not exist.");
return Task.CompletedTask;
}
where types A and B are treated identically. I am therefore experimenting if these conditions can be merged to obtain more concise code!
Would it be possible to write something like
if (A == null || B == null)
{
errors.Add(nameof(A/B), "A/B does not exist."); // When A == null, use A. When B == null, use B.
return Task.CompletedTask;
}
where we can retrieve information about which type is null? In other words, can we find out which of the conditions in the if-statement was satisfied?
Thanks in advance!

You could use ternary operator.
if (A == null || B == null)
{
errors.Add(nameof(A == null ? A : B), $"{A == null ? "A" : "B"} does not exist."); // When A == null, use A. When B == null, use B.
return Task.CompletedTask;
}

Related

How to handle NULL when using String.StartsWith method

How do I handle a null when using the String.StartsWith() in a complex where clause ?
var value = _context.Repo.Pages.Where(r => r.Sdate <= data.Pdate && (r.Edata == null || data.RData <= r.Edata)
&& ......
&& ...... several conditions
&& ......
|| (data.SisPlan.StartsWith("T") && r.SisN == data.SisCal));
I've tried data?.SisPlan.StartsWith("T") but get the message:
Operator '&&' cannot be applied to opperands of type 'bool?' and
'bool'
I'm trying to prevent doing a null check outside of the where clause.
The usual way is to write:
|| ((data?.SisPlan?.StartsWith("T") ?? false) && r.SisN == data.SisCal));
We rely on the ?? operator to get the null case and in this case we return a false value. The ?? is called the null coalescing operator.
Basically,
var a = data?.SisPlan?.StartsWith('T') ?? false;
is a syntaxic sugar for
bool a = false;
if (data != null && data.SisPlan != null && data.SisPlan.StartsWith('T'))
a = true;

Efficient way for multiple 2 value true false if statement

I have an if else statements that has 2 values that need to be evaluated whether they're null or not, then based on that, it chooses the right statement. The code below:
int? x;
int? y;
if(x == null and y == null) { do this part; }
else if (x != null and y == null) {do this second part; }
else if (x == null and y != null) {do this third part; }
else { do this last part; }
I am trying to find if there is a more efficient way to implement this. There is the option of a case statement, but I still want to know if there is a better way.
I'd use a nested if, so each variable is only evaluated once, instead of multiple times as suggested in the OP snippet.
if (x == null) {
if (y == null) {
// Both are null
} else {
// Only x is null
}
} else {
if (y == null) {
// Only y is null
} else {
// Neither are null
}
}

Convert Multiple if condition into Ternary Operator

I want to convert below condition to ternary
if (!string.IsNullOrEmpty(objModel.Status))
{
if (objModel.Status == "0")
{
Model.Sort = "Result1";
}
else if (objModel.Status == "8")
{
Model.Sort = "Result2";
}
else
{
Model.Sort = "Result3";
}
}
I have tried as below but it went upto if and else not else if
Model.Sort = !string.IsNullOrEmpty(Model.Status)
? (Model.Status == "0" ? Retult1 : string.Empty)
: string.Empty;
Keep a local variable for simplification
var x = objModel.Status;
if (string.IsNullOrEmpty(x))
{
Model.Sort = x=="0" ? "Result1" :
x=="8" ? "Result2" :
"Result3";
}
you can have ternary operator like this
a ? b : c ? d : e
to get this:
if (a) {
b
}
else if (c) {
{
d
}
else {
e
}
in your case
objModel.Status == "0" ? Model.Sort = "Result1" : objModel.Status == "8" ? Model.Sort = "Result2" : Model.Sort = "Result2";
I hope this helps.
You can write your code using ternary operators like this:
Model.Sort = string.IsNullOrEmpty(objModel.Status) // if (string.IsNullOrEmpty(Status))
? Model.Sort // Model.Sort = Model.Sort;
: objModel.Status == "0" // else if (Status == "0")
? "Result1" // Model.Sort = "Result1";
: objModel.Status == "8" // else if (Status == "8")
? "Result2" // Model.Sort = "Result2";
: "Result3"; // else Model.Sort = "Result3";
Where the first condition represents the if condition, and then each statement after a : operator that is a comparison represents an else if, and finally the result after the last : represents the final else assignment.
The first condition is kind of a "dummy" condition (because if it's true nothing really changes*), but is required if we want to include the IsNullOrEmpty check in the ternary operations, since the ternary operator has to return a value in both the true and false cases.
I'm not sure if the dummy assignment would get optimized away or if the setter is called in that "dummy" case. If the setter is called then potentially this could have a different effect than your original code, depending on what the setter code does.

Due to LINQ Retrieving of Record data's i have this error: NullReferenceException was unhandled by user code

private void getUserLoginDepartment(string AccessID, string UserPROFid)
{
try
{
DBWPAccountRecordsDataContext DBACCOUNT = new DBWPAccountRecordsDataContext();
var query = (from i in DBACCOUNT.WP_UserAccessPorts
join
z in DBACCOUNT.WP_Departments on i.AccessPortID equals z.Dept_ID
where i.AccessPortID == AccessID && i.ProfileUser_ID == UserPROFid
select new
{
PORT1 = i.AccessPoint1,
PORT2 = i.AccessPoint2,
PORT3 = i.AccessPoint3,
PORT4 = i.AccessPoint4,
DEPT = z.Dept_DESC,
DEPTPORT = z.Dept_PortNo
}).FirstOrDefault();
if (query.PORT1.ToString() != null || query.PORT1.ToString() != string.Empty)
{ Session["Port1"] = query.PORT1; }
else { Session["Port1"] = ""; }
if (query.PORT2.ToString() != null || query.PORT2.ToString() != string.Empty)
{ Session["Port2"] = query.PORT2; }
else { Session["Port2"] = ""; }
if (query.PORT3.ToString() != null || query.PORT3.ToString() != string.Empty)
{ Session["Port3"] = query.PORT3; }
else { Session["Port3"] = ""; }
if (query.PORT4.ToString() != null || query.PORT4.ToString() != string.Empty)
{ Session["Port4"] = query.PORT4; }
else { Session["Port4"] = ""; }
}
finally
{
}
}
The Error occures when i reach break point 1st IF Statement the record on my database shows that its not empty which its value is "WebAdmin" but then suppost to be it should pick it up and store it to the Session["PORT1"] that i have made is there something i missed or i'm doing it wrong on my linq Query. NOTE:*This is an ASP.NET C# Application
EDIT 10/2/2013 0420PM:
It's still an Error After using that method sir.
1) you should check query for null when you use FirstOrDefault
2) you need to check each PORTX for null
3) use string.IsNullOrEmpty( ) to check if the string of PORTX is null
var query = ( ... ).FirstOrDefault( );
if( query != null )
{
if( query.PORT1 != null && !string.IsNullOrEmpty( query.PORT1.ToString( ) ) )
{
}
else { ... }
}
You have to check query.PORT1 for null before calling ToString on it, you can use String.IsNullOrEmpty to check both conditions. Before checking query.PORT1 you need to check if query is null or not. You also need to use && instead of or operator as || will cause the right side of or operator to be evaluated if left is false and on right side calling ToString on null will again through exception.
if (query != null && query.PORT1 != null && query.PORT1.ToString() != string.Empty)
{ Session["Port1"] = query.PORT1; }
Using IsNullOrEmpty
if(query != null && !String.IsNullOrEmpty(query.PORT1))
{
Session["Port1"] = query.PORT1;
}

C# short-circuiting weirdness

Given a = null
Shouldn't this not throw an exception?
if(a != null && ((string)a).ToLower()=="boo"){
... operation
}
Due to lazy evaluation the second statement should never be called so this ((string)a).ToLower() shouldn't be throwing an exception right ?
UPDATE
IOrderedEnumerable<SPListItem> Items = sourceList.GetItems("ProjectID", "Title", "ProjectName", "Featured", "Size", "Description")
.Cast<SPListItem>().AsEnumerable().OrderBy((i => rnd.Next()));
SPListItemCollection randProjImages = SPContext.Current.Web.Lists.TryGetList("Random Projects Images").GetItems();
var randomImgNrs = Enumerable.Range(0, randProjImages.Count).OrderBy(i => rnd.Next()).ToArray();
Dictionary<string, string> projectImages = new Dictionary<string,string>();
IEnumerable<SPListItem> projImages = SPContext.Current.Web.Lists.TryGetList("Assigned Projects Images").
GetItems().Cast<SPListItem>().AsEnumerable();
foreach (SPListItem it in projImages) projectImages.Add((string)it["ProjectID"], (string)it["ServerUrl"]);
int qCount = 0;
foreach (SPListItem item in Items) {
if (item["Size"] != null && item["Featured"]!=null &&
((string)item["Size"]).ToLower() == "big" || ((string)item["Featured"]).ToLower() == "yes") {
dataItems.Add(new Project(item["ProjectID"].ToString(), (string)item["Title"],
"/sites/Galileo/SitePages/" + Utils.getCurrentLang().ToLower() + "/Projects.aspx#id=pwp" + item["ProjectID"],
projectImages[(string)item["ProjectID"]],
Utils.truncateString(item.Fields["Description"].GetFieldValueAsText(item["Description"]), 175), "project"));
}else{
Replacing the foreach with this:
foreach (SPListItem item in Items) {
var k = item["Size"];
if (item["Size"] != null && item["Featured"]!=null &&
((string)item["Size"]).ToLower() == "big" || ((string)item["Featured"]).ToLower() == "yes") {
dataItems.Add(new Project(item["ProjectID"].ToString(), (string)item["Title"],
"/sites/Galileo/SitePages/" + Utils.getCurrentLang().ToLower() + "/Projects.aspx#id=pwp" + item["ProjectID"],
projectImages[(string)item["ProjectID"]],
Utils.truncateString(item.Fields["Description"].GetFieldValueAsText(item["Description"]), 175), "project"));
}else{
And breaking just before the if statement in the debugger, k == null
if (item["Size"] != null && item["Featured"]!=null &&
((string)item["Size"]).ToLower() == "big" || ((string)item["Featured"]).ToLower() == "yes")
it goes to the ((string)item["Featured"]).ToLower() == "yes")
No exception:
string a = null;
if (a != null && ((string) a).ToLower() == "boo")
string a = "";
if (a != null && ((string) a).ToLower() == "boo")
string a = "boo";
if (a != null && ((string) a).ToLower() == "boo")
this is as it should be (though the casting is unnecessary).
Does not compile:
T a = new T();
if (a != null && ((string) a).ToLower() == "boo")
T? a = null;
if (a != null && ((string) a).ToLower() == "boo")
T? a = new T();
if (a != null && ((string) a).ToLower() == "boo")
where T is any type other than string due to casting from T to string.
The real question is: Why do think it throws an exception?
Use
String.IsNullOrWhiteSpace(a)
You are right that the second argument of && is not evaluated if the first argument is false (a is null). So the code cannot throw a NullReferenceException. However, if a is not null but an object that cannot be cast to string, the code can throw an InvalidCastException.
Note that the best practice for comparing strings in a case-insensitive way is to use the String.Equals Method:
if (String.Equals(a, "foo", StringComparison.CurrentCultureIgnoreCase))
{
// ... operation
}
Since the method is static, no null-check is needed.
Exactly, this will not throw an exception. Since your expression is AND, evaluating only the first part is enough to know that it will never evaluate to true, so the second part is skipped.
Correct! (except that it's not called lazy evaluation)
If the first operand evaluates to true, the second operand isn't evaluated.
http://msdn.microsoft.com/en-us/library/vstudio/6373h346.aspx

Categories