Understanding c# syntax of return statement - c#

I'm attempting to understand the syntax of a piece of code someone else wrote.
The method is returning a bool, and the return statement looks like this:
return user.UserStatus == Models.User.UserStatuses.Inactive && user.IsLocked;
UserStatuses is a enum.
So it appears to me it returns the property of object user called UserStatus, however UserStatus is an enum, not a bool, and then && adds the bool as user.IsLocked, where is a bool.
I can't seem to understand how this is legal in c#, since it appears to return two parameters.

Add some parenthesis, or separate your line into multiple statements, and it makes sense. The compiler is just doing it for you (more or less). Your statement is equivalent to:
return ((user.UserStatus == Models.User.UserStatuses.Inactive) && user.IsLocked);
or
bool inactive = user.UserStatus == Models.User.UserStatuses.Inactive;
bool inactiveAndLocked = inactive && user.isLocked;
return inactiveAndLocked;
The key here is that return is taking an expression (not a parameter) and using the result of that expression, which is just one "thing" as the C# spec dictates.

bool result = (user.UserStatus == Models.User.UserStatuses.Inactive) &&
user.IsLocked;
return result;

It is just returning a boolean condition. Hypothetically, you could also check that same code on a IF statement like:
if(user.UserStatus == Models.User.UserStatuses.Inactive && user.IsLocked)

UserStatus is an enum but the base type of an enum is int. This is compared to the specific enum type. So the first part is basically (int == int) which yields a bool. The bool is then conditionally and'ed with the IsLocked value (bool && bool) to yield the final result.

Related

Validate null object

In order to validate if model comes null or not I use something like this:
if (model is null || !model.Any()) return this;
But in latest Microsoft conference I saw guys use something like:
if(model is { })
I try to use it but always return true (if object comes null or not)
So my question is. Is there a new way to check if a model comes null?
What is the correct usage of brackets { }
Note: I googled about that brackets but I found anything. Regards
You can do a generic extension method to check if your object is null or not.
Try:
public static bool IsNullOrEmpty<T>(this IEnumerable<T> source) {
return source?.Any() != true;
}
Another way to check for NullOrEmpty is to coerce Count() to an int?. Then we can compare the result of GetValueOrDefault to 0:
if((model?.Count).GetValueOrDefault() == 0) return this;
How it works:
Because the ?. operator will return null if the left side is null, and Count returns an int, the result of (model?.Count) is a Nullable<int>.
The GetValueOrDefault method returns the value of Count if model is not null, otherwise it returns default(int) (which is 0).
This way if model is null, the condition returns 0

Find object that meets multiple conditions using LINQ

I am trying to find an object in my database that meets two conditions, I did a search on stackoverflow and found this one which looks exactly like what I need. However, I have this code:
if (db.MinimumProductInfo.Find(pc => pc.ItemCode == productInfoWithNote.ItemCode && pc.Region == productInfoWithNote.Region))
and I am receiving this error:
Cannot Convert Lambda Expression to type 'object[]' because it is not
a delegate type.
MinimumProductInfo is my class and productInfoWithNote is the viewmodel that I pass in to the method.
Try using FirstOrDefault which will return null if no object meets the conditions:
var myObject = db.MinimumProductInfo.FirstOrDefault(pc => pc.ItemCode ==
productInfoWithNote.ItemCode && pc.Region == productInfoWithNote.Region);
if(myObject != null)
{
// use your object here
}
NOTE: Find method returns the first match element if exists and if not it will return the default value of element's type and you are using it like it will return a boolean value.

What does Return myVar != null actually mean?

Resharper is a great tool, but it sometimes confuses me as to what the suggested code really means. I have this code:
private bool DoesUserExists()
{
var user = De.Users.FirstOrDefault(u => u.Username == CurrentUser.Username);
return user != null;
}
I originally had :
if(user == null)
return false;
else
return true;
But Resharper suggested the top code. However, that looks to me to be saying return user if it is not null. But the method only accepts a bool return and not a class.
So what does return user != null actually return when it is null and when it is not?
So what does return user != null actually return when it is null and
when it is not
It simply evaluates the expression. If user is null it returns false and if user isn't null, it returns true.
Think of this as if you were assigning the result of the comparison to a local variable, and only then returning it:
bool isNotNull = user != null;
return isNotNull;
Or:
bool isNull = user == null;
return !isNull;
isNotNull would be true only iff the user variable is not null.
Semantically, it is identical to your if-else statement.
Not sure I'm adding any value here, #Yuval's answer is correct and clear, but maybe it helps to see it this way.
You are thinking of parsing the code something like this:
(return user) (!= null)
That is, you see "return user" and wonder what the rest of the line is doing there. But return doesn't work that way. It evaluates the rest of the line, and returns that. It's more like
(return) (everything else)
or, in the specific case
(return) (user != null)
Where return gets executed last.
It is much like operator precedence, where 3+5*2 must be evaluated as 3+10 instead of 8*2, because * has higher precedence (must be evaluated first) than +. return has the lowest precedence of all.
If you learn to read and write code with this in mind, you will find yourself appreciating the refactored code.

Trying to convert VB.NET code to C#. IsDBNull issue

I dont know how much code you would need but if you would like more id be happy to oblige
here is my attempt so far:
if(AliasNum == null || IsDBNull(AliasNum)
return
Here is the VB code that Im trying to convert
If AliasNum = Nothing Or IsDBNull(AliasNum) Then
Exit Sub
End If
Based on your comment, AliasNum is of type string. Maybe you want:
if (AliasNum == null || AliasNum.Length == 0)
return;
You can use the DBNull.Value.Equals Method to determine if the value is equal to DBNull.
if(AliasNum == null || DBNull.Value.Equals(AliasNum)
return
The "IsDBNull" function you are calling in the original VB code is from the Microsoft.VisualBasic.Information module. The closest .NET equivalent is the System.Convert.IsDBNull method:
if (AliasNum == null || System.Convert.IsDBNull(AliasNum))
{
return;
}
Also, the original "AliasNum = Nothing" syntax suggests that "AliasNum" is an instance of a value type, so you may need to change "AliasNum == null" to "AliasNum == default value of the type of AliasNum".

Lambda expressions query null field

Well, I have the following query that I use to search a LIST with the text that the user has filled.
It's only one textbox that search in all these fields below, it's working but when one of these fields is null, it's throwing a null reference exception, how can I avoid that?
List<REP_MEDIDORDISPLAY> SearchFiltered = new List<REP_MEDIDORDISPLAY>();
if (filter != String.Empty)
{
SearchFiltered.Clear();
foreach (String Item in filter.Split(';').ToList<String>())
{
SearchFiltered.AddRange(Medidores.Where(x => x.Data_TOI.Contains(Item.Trim()) ||
x.Elemento.ToUpper().Contains(Item.Trim()) ||
x.Fase.ToUpper().Contains(Item.Trim()) ||
x.ID.ToUpper().Contains(Item.Trim()) ||
x.KdKe.ToUpper().Contains(Item.Trim()) ||
x.N_Equipamento.ToUpper().Contains(Item.Trim()) ||
x.Status.ToUpper().Contains(Item.Trim()) ||
x.Tensao.ToUpper().Contains(Item.Trim())));
}
}
I hope you guys can help me. thanks.
By checking for null first:
(x.Elemento != null && x.Elemento.ToUpper().Contains(Item.Trim())) ||
// etc
Of course you should also calculate Item.Trim() just once and reuse this value for all tests rather than trimming as many times as there are fields.
You can add null check to each of the properties. Example:
From
x.Fase.ToUpper().Contains(Item.Trim()) ||
To
(x.Fase != null && x.Fase.ToUpper().Contains(Item.Trim())) ||
Maybe you should introduce something like a null object. This object is empty and will therefore always return false on every query against it.
If you implement nullchecks for every property on that object your code will rot over time. And you are gonna have a bad time.
There are many ways to do what you are doing, some more elegant perhaps.
One simple way could be to override the ToString method in the object in the Medidores sequence and use that for the comparison.
Something like this:
class Medidor {
... properties
public override string ToString() {
return Data_TOI + Elemento ... etc
}
}
And then you could compare against that instead.
SearchFiltered.AddRange(
Medidores.Where(x =>
x.ToString()
.IndexOf(Item.Trim(), 0, StringComparison.InvariantCultureIgnoreCase) != -1
);
I'm using IndexOf as it has an overload that takes StringComparison.InvariantCultureIgnoreCase, which ignores casing among other things.
The reason why I think this approach is preferred to what you have now, is that the Meridor object itself is responsible for what fields are included in the ToString method. Maybe it can improve readability and maintainability.

Categories