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

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".

Related

Understanding c# syntax of return statement

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.

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.

Creating an ambiguous test

I had an idea about creating a bool isNull that can be used pretty much ambiguously wherever needed. The original idea was as follows (pseudo-code only):
bool isNull(var test)
{
if (test == null || DBNull || string.Empty)
return true;
else
return false;
}
But this doesn't work, as var is not recognised here. Instead, it appears to be assumed that var refers to a type... well I, of course, don't have a type for var!
What do I do to get around this? Or, perhaps the question I should be asking, Is this a good idea at all?
Why don't you use object ?
bool isNull(object test)
{
if (test == null || test == DBNull.Value)
return true;
else
return false;
}
For strings, I would use string.IsNullOrEmpty method.For other types, especially when you are dealing with databases this function can be useful.
Your code isn't working because var will be resolved at compile-time.
You could use object or dynamic as type. dynamic will be resolved at run-time

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.

How to cater for an object which can be both null or empty

I've got an object, specifically the following:
table.ExtendedProperties["MS_Description"].Value
If there is not property, the Value is null. If there is a property, but it is empty, the Value.toString() is "".
I would thus like to create an if-statement which caters for both eventualities. This is what I've done so far:
if (table.ExtendedProperties["MS_Description"] == null ||
table.ExtendedProperties["MS_Description"].Value.ToString().Equals(""))
The problem is that if it is null, it is still checking the condition on the right-hand-side.
Any ideas?
You can do:
if (table.ExtendedProperties["MS_Description"] == null || string.IsNullOrEmpty(table.ExtendedProperties["MS_Description"].Value))
The reason your code errors is because you don't check if table.ExtendedProperties["MS_Description"].Value is null.
Thus Value is not a string, then you have to deal with all conditions:
var description = table.ExtendedProperties["MS_Description"];
if (description == null ||
description.Value == null ||
description.Value.ToString().Equals(""))
// no value
BTW your code is not quite correct
if (table.ExtendedProperties["MS_Description"] == null ||
table.ExtendedProperties["MS_Description"].Value.ToString().Equals(""))
Instead of checking Value for null, you are checking if table.ExtendedProperties["MS_Description"] is not null. Thats true. You go further, but if table.ExtendedProperties["MS_Description"].Value is null (you didn't check that, remember?), you will get NullReferenceException on applying ToString().
I'm not sure if you are referring to the DataTable.ExtendedProperties property or something else, but if you are, the property returns a System.Data.PropertyCollection, which inherits from System.Collections.HashTable.
Most of the methods and properties, including the indexer ("Item") being discussed here, are directly inherited from HashTable, so in general, table.ExtendedProperties[key] can return any object, including null.
Note that you can also call DataTable.ExtendedProperties.ContainsKey(object key) to determine if the PropertyCollection contains a specific key or not.
Do you know what type of object you are retrieving when you call table.ExtendedProperties["MS_Description"].Value ?
If so, there might be other properties you can use to determine whether the property has been set, etc.
Depending on what type of object table.ExtendedProperties["MS_Description"] is, you might even be able to do something like this:
if ((table.ExtendedProperties["MS_Description"] ?? "").ToString().Length == 0) {
.....
}
That would take into account all of the possibilities:
the key doesn't exist
the key exists, but the value is null
the key exists and the value is empty
as long as the table.ExtendedProperties["MS_Decription"] object returns "" when its Value property is either null or empty.
So a little more information on the object that is returned could go a long way!
string.IsNullOrEmpty(table.ExtendedProperties["MS_Description"].Value)
It looks like table.ExtendedProperties["MS_Description"] is never null, you should be null checking the Value property instead
string value = table.ExtendedProperties["MS_Description"].Value;
if (value == null || value.ToString().Equals(""))
// OR
if (String.IsNullOrEmpty(value))
If table.ExtendedProperties["MS_Description"] can return null, then you need
if (table.ExtendedProperties["MS_Description"] == null ||
String.IsNullOrEmpty(table.ExtendedProperties["MS_Description"].Value.ToString() )
And since table.ExtendedProperties["MS_Description"].Value may return null, then you need
if (table.ExtendedProperties["MS_Description"] == null ||
table.ExtendedProperties["MS_Description"].Value == null ||
String.IsNullOrEmpty(table.ExtendedProperties["MS_Description"].Value.ToString() )

Categories