I have a DataGridView cell that is of type System.Single.
if (myDataGridView.Rows[0].Cells[1].Value == null)
{
//some code
}
myDataGridView.Rows[0].Cells[1].Value has value {}. It's not null, nor is it 0, what should be on the right hand side of == to make the conditional true?
It's something called DBNull.Value as stated before you can use it:
if (myDataGridView.Rows[0].Cells[1].Value == DBNull.Value)
{
//some code
}
As noted, the value is an instance of DbNull.
Given that DbNull.Value is a singleton (and thus safe for reference comparisons), two options come to mind:
if (myDataGridView.Rows[0].Cells[1].Value == DBNull.Value)
or
if (myDataGridView.Rows[0].Cells[1].Value is DbNull)
Personally I quite like that latter - it fits in with the "is null" approach within a database, and it reads well... it makes it clearer that I'm interested in nullity as a sort of property rather than performing an actual equality comparison.
Have you tried this?
if (DBNull.Value.Equals(myDataGridView.Rows[0].Cells[1].Value))
{
//some code
}
Related
I've got the following code:
// Here is where we will read in all our values and populate the form with them
lblBenCatX.Text = Convert.ToString(reader["Category"]);
lblBenProvX.Text = Convert.ToString(reader["Provision"]);
txtCommentBox.Text = Convert.ToString(reader["Feedback"]);
ddlDefect1.SelectedValue = Convert.ToString(reader["Network"]);
ddlIssue1.SelectedValue = Convert.ToString(reader["Issue_ID"]);
ddlResolution1.SelectedValue = Convert.ToString(reader["Resolution_ID"]);
ddlDefect2.SelectedValue = Convert.ToString(reader["Network2"]);
ddlIssue2.SelectedValue = Convert.ToString(reader["Issue_ID2"]);
ddlResolution2.SelectedValue = Convert.ToString(reader["Resolution_ID2"]);
The first 3 rows of code; no problem. However, if I have a record with a NULL value, the dropdowns break the code. So, I'm thinking I need to check the field first to make sure it's not NULL. Something like:
if (!Convert.ToString(reader["Network"]) = NULL)
{
ddlDefect1.SelectedValue = Convert.ToString(reader["Network"]);
}
However, that's giving me an error:
The left-hand side of an assignment must be a variable, property or
indexer
Any ideas? This is C# in VS2015 with an Oracle back end, if any of that matters.
In C#, you need to use two equal signs in a row == for equality comparison, not one. One equal sign = is an assignment operator.
if (first == second) { ... }
In your case, though, you would want to use the "not equals" != operator:
if (Convert.ToString(reader["Network"]) != null)
Which is cleaner and slightly more-efficent than this:
if (!(Convert.ToString(reader["Network"]) == null))
Note that I've wrapped the whole inner comparison in parens so the whole statement is being negated; otherwise, it will think you're trying to say !Convert.ToString(reader["Network"]), and, as you pointed out in the comments here, you can't use ! with a string.
That being said, if you're converting to string, then it's better to use string.IsNullOrEmpty() for checking:
if (!string.IsNullOrEmpty(reader["Network"].ToString())))
But the best is probably to just check if the column value is null, rather than converting it to string:
if (!reader.IsDBNull(["Network"]))
= is an assignment operator, used when setting values.
== is an equality operator, which determines whether something is equal to something else.
!= is also an equality operator, opposite to the one above. So, when something is not equal to something else.
So actually, you should be using != in this scenario:
if (Convert.ToString(reader["Network"]) != null)
{
ddlDefect1.SelectedValue = Convert.ToString(reader["Network"]);
}
You have a couple of choices. The first is to check if the value is DBNull which is different than an empty string/null value.
if (!reader.IsDBNull([ordinalPositionOfNetworkInSelectStatement]))
ddlDefect1.SelectedValue = Convert.ToString(reader["Network"]);
See IDataReader.IsDBNull. The only thing is that you need to know the ordinal position of the column you are checking.
The alternative is to check for dbnull in your sql select statement and use a function to return an empty string if it is. The positive side of this approach is you do not have to worry about checking for null in your c# code but I am not sure if it has any negative consequences in your oracle query or view. You can do this with COALESCE.
SELECT Category, Provision, Feedback, COALESCE(Network, '') AS Network /*other columns*/
FROM ... -- rest of the query
disclaimer - my oracle syntax is lacking but COALESCE does exist as a function
With numeric it is always same pretty:
if(a < 123) { ... } // disregards if `b` is `int?` or `int`
But with bool?:
bool? b = ...
if(b) { ... } // compiler error: can't convert bool? to bool.
There are following options:
if(b == false) { ... } // looks ugly, comparing bool? with bool
if(b.GetValueOrDefault()) { ... } // unclear when condition is true (one must know it's `false`)
if(b.GetValueOrDefault(true)) { ... } // required few seconds to understand inversion
I was curios whenever nullables (at least bool?) deserves this syntax to be used always:
if(b ?? false) { ... } // looks best to me
P.S.: this may looks like opinion-based question, but I didn't find similar to clear all my doubts alone... Perhaps some of those are best used in certain scenarios and I'd like to know in which ones.
The language designers had two choices, as far as allowing bool? to participate in control expressions of control statements requiring a bool:
Allow it, and make an arbitrary decision when it comes to null treatment
Disallow it, forcing you to make a decision each time it is relevant.
Note that the designers had much less of an issue with if(a < 123) statement, because "no" is a valid answer to questions "is null less than 123", "is null greater than 123", "is null equal to 123", and so on.
The if (b ?? false) and if (b ?? true) are very convenient constructs, which let you explain to the readers of your code and to the compiler in which way you wish to treat nulls stored in a bool? variable.
Every time I see someone using a nullable boolean bool?, I ask them why. Usually, the answer is -- "well, I'm not really sure". It is effectively creating a three state condition which in my opinion makes the code harder to read regardless. What does null mean, if it is always false then why bother with making it nullable in the first place?
But to answer your question more directly, I prefer the
if (b ?? false)
syntax over the
if (b.GetValueOrDefault())
Some years later and from personal experience I can tell that following syntax is clearly a winner:
if(b == false) { /* do something if false */ }
if(b == true) { /* do something if true */ }
if(b != false) { /* do something if NOT false, means true or null */ }
if(b != true) { /* do something if NOT true, means false or null */ }
What I thought as "ugly" turns out to be the easiest to understand.
== vs ??
Nullables are often results of linq queries and using ?? add unnecessary layer of complexity to understand the condition.
Compare
if(Items?.Any(o => o.IsSelected) == true)
vs
if(Items?.Any(o => o.IsSelected) ?? false)
The first one is much easier to read, it's a simple check if any item is selected.
When my (probably untrained?) mind reads the latter, I have to make a mental full stop at ??, do inversion and only then I understand when if block will be executed. With ?? I am likely to make a mistake when quickly looking throught the code written by someone else or even my own code given enough time has passed.
how do i convert follow code to one line if else
if (data.BaseCompareId == 2)
report.Load(Server.MapPath("~/Content/StimulReports/MonthGroup.mrt"));
else
report.Load(Server.MapPath("~/Content/StimulReports/YearGroup.mrt"));
i try this code but did not work
data.BaseCompareId == 2
? report.Load(Server.MapPath("~/Content/StimulReports/MonthGroup.mrt"))
: report.Load(Server.MapPath("~/Content/StimulReports/YearGroup.mrt"));
Try with this instead :
string path = data.BaseCompareId == 2
? "~/Content/StimulReports/MonthGroup.mrt"
: "~/Content/StimulReports/YearGroup.mrt";
report.Load(Server.MapPath(path));
Since report.Load() returns a void, it wont work.
Edited version :
string s = data.BaseCompareId == 2
? "MonthGroup.mrt"
: "YearGroup.mrt";
report.Load(Server.MapPath("~/Content/StimulReports/" + s));
I am assuming report.Load returns a void, hence it "doesn't work". That said, why are you doing this? The first example is perfectly clear.
If you want are going to use ?: here use it so only the part which is actually different is in the branching statement:
string fileName = (data.BaseCompareId == 2) ? "MonthGroup.mrt" : "YearGroup.mrt";
report.Load(Server.MapPath("~/Content/StimulReports/" + fileName));
If you want to use a ternary operator, you can do:
report.Load(data.BaseCompareId == 2 ? Server.MapPath("~/Content/StimulReports/MonthGroup.mrt") : Server.MapPath("~/Content/StimulReports/YearGroup.mrt"));
Or (better):
report.Load(Server.MapPath(data.BaseCompareId == 2 ? "~/Content/StimulReports/MonthGroup.mrt" : "~/Content/StimulReports/YearGroup.mrt"));
(Or you could further exploit the similarity in the two strings, as #helb's answer does.)
As has already been noted, your way doesn't work because you're trying to replace a conditional statement with a conditional expression, and conditional expressions have to have a value. Since report.Load apparently returns void, a conditional expression of the form cond ? report.Load(...) : report.Load(...) doesn't have a value, ergo it doesn't work.
Each of the ways above will work because the conditional expressions in them have values - in the first case, the value will be of the type returned by Server.MapPath; in the second case, the value will be of type string.
As to whether you should do this: there are arguments to be made either way. The original way has the advantage of being clear and simple, but it does involve some (arguably undesirable) repetition. The latter approach above has the advantage of only saying things once and emphasising the intent of the whole statement (to load a report), but it's arguably slightly less clear than the original, depending on how used people are to seeing conditional expressions. YMMV.
This syntax is just for cases where it returns something. So you could do something like:
var path = (data.BaseCompareId == 2) ? "~/Content/StimulReports/MonthGroup.mrt" : "~/Content/StimulReports/YearGroup.mrt";
report.Load(Server.MapPath(path));
This is the most concise I could get for a one-liner...
report.Load(Server.MapPath(string.Format("~/Content/StimulReports/{0}Group.mrt", data.CompareId == 2 ? "Month" : "Year")));
However, it seems you just want to make things look cleaner.
More abstraction between data calls and the conditional logic.
You might want to consider making them separate methods, perhaps on your report object?
if(data.CompareId == 2)
report.LoadStimulReports(ReportGroup.Month);
else
report.LoadStimulReports(ReportGroup.Year);
Using an enum, extension method, and static method on your report object...
public enum ReportGroup
{
[DescriptionAttribute("~/Content/StimulReports/MonthGroup.mrt")]
Month,
[DescriptionAttribute("~/Content/StimulReports/YearGroup.mrt")]
Year
}
public static T GetAttribute<T>(this Enum e) where T : Attribute
{
System.Reflection.FieldInfo fi = e.GetType().GetField(e.ToString());
object[] o = (object[])fi.GetCustomAttributes(typeof(T), false);
return o.Length > 0 ? (T)o[0] : default(T);
}
public static void LoadStimulReports(ReportGroup reportGroup)
{
report.Load(Server.MapPath(reportGroup.GetAttribute<DescriptionAttribute>().Description));
}
Now you can simply add another item to the enum if you need another report.
[DescriptionAttribute("~/Content/StimulReports/WeekGroup.mrt")]
Week
I have to modify a Visual Studio 2010 C# project that works with Oracle, looking at some code I've found a function that returns a List<> with values loaded from a database stored procedure (cursor)
while (myIDataReader.Read())
{
// OK
myTable.myStringField = myIDataReader["TableStringField"].ToString();
// ¿?
myTable.myIntField =
Convert.ToInt32((myIDataReader["TableIntField"] == DBNull.Value) ? null : myIDataReader["myTableField"]);
}
Everything's ok, just want to know, what conditions are given when assign myTable.myIntField, I know this column is nullable, but I don't get the syntax, if someone can explain I'll be thankful
You are talking about this line?
myTable.myIntField =
Convert.ToInt32((myIDataReader["TableIntField"] == DBNull.Value) ? null : myIDataReader["myTableField"]);
If you break that statement apart, you have a type of conditional, often called the Ternary operator, explained here.
conditional ? if_true_do_this : if_false_do_this
It is really just a different syntax for:
if(conditional) {
if_true_do_this;
} else {
if_false_do_this
}
After that, it simply passes the result to Convert.ToInt32() to turn it from a string into an int.
So that line of code is just a more concise version of this:
if(myIDataReader["TableIntField"] == DBNull.Value)
{
myTable.myIntField = Convert.ToInt32(null);
}
else
{
myTable.myIntField = Convert.ToInt32(myIDataReader["myTableField"]);
}
The syntax above works correctly and it means:
TableIntField could contains a database null.
This is expressed in NET via the DBNull object and its Value field.
The code checks if the TableIntField contains the DBNull.Value via C# ternary operator.
If the checks result in a true condition, a null is used as argument for Convert.ToInt32 and this, according to MSDN documentation, result in a zero value assigned to myTable.myIntField.
Hello I was thinking of what is better to write (in matter of speed and/or efficiency):
bool Method(...) { ... }
...
bool result = Method(...);
if (result == false)
{ ... }
// or
if (!result)
{ ... }
Or, alternatively...
if (result == true)
// or
if (result)
I'm asking because I use first one (result == false) but sometimes it gets very long, especially in condition ? expr : expr statements.
Personally, I cringe whenever I see something like result == false. It's a rather nasty misuse of the equality operator in my opinion, and totally unnecessary. While I'd imagine the compiler should turn the two expressions into the same byte code, you definitely want to be using !result. Indeed, it is not only the more direct and logical expression, but as you mention, makes the code a good deal shorter and more readable. I think the vast majority of C# coders would agree with me on this point.
Runtime speed is the same - both snippets compile to the same MSIL code representation.
Using (result == false) instead of (!result) feels kinda sloppy though.
There is no performance difference in runtime code. Most of the coding-guidelines in the companies i worked prefer !result.
I don't think there is any difference, and if there is you would probably have a hard time measuring it. Any difference is likely to be in the noise of the measurement.
You should definitely use the expression with the ! operator, not because it's faster but because it's safer.
If you accidentally use one equals sign instead of two, you assign the value to the variable instead of comparing the values:
if (result = false) {
For other data types the compiler can catch this, as an expression like (id = 42) has an integer value so it can't be used in the if statement, but an expression like (result = false) has a boolean value so the compiler has to accept it.
(An old C trick is to put the literal first so that it can't be an assignment, but that is less readable so the ! operator is a better alternative.)
I think there are three steps in this process. First, you believe that there should always be a comparison inside an if, so you write if(this.isMonkey == true) banana.eat();
Or, more realistically
if(SpeciesSupervisor.getInstance().findsSimilarTo(Monkey.class, 2) == true) {
String f = new PropertyBundle("bananarepo").getField("banana store");
EntitiyManager.find(Banana.class,f).getBananas().get(1).eat();
}
Then, you learn that it is fine to ask if(this.isMonkey) and that this formatting allows better reading as a sentence in this example ("if this is a monkey").
But at last, you get old and you learn that if(b) is not very readable, and that if(b==true) gives your poor brain some clue what is happening here, and that all these harsh claims of "misuse", "abuse", yada yada, are all a little overstated.
And as for the performance. In Java it would not make a shred of difference. I don't think .NET is so much worse. This is the easiest optimization a compiler could do, I would bet some money that the performance is the same.
Cheers,
Niko
Although I agree with #Noldorin that if(!result) is to be preferred, I find that if(result == false) and its ilk are very useful if you have to test a nullable bool, which most frequently happens in data access scenarios.
Edit: Here's a sample program that explains the different ways you can use the equality operator on a nullable bool.
class Program
{
static void Main(string[] args)
{
TestNullBool(true);
TestNullBool(false);
TestNullBool(null);
Console.ReadKey();
}
private static void TestNullBool(bool? result)
{
if (result == null)
{
Console.WriteLine("Result is null");
}
if (result == false)
{
Console.WriteLine("Result is false");
}
if (result == true)
{
Console.WriteLine("Result is true");
}
}
}
/* Output:
Result is true
Result is false
Result is null
*/