Decimal? - Nullable object must have a value - asp.net-mvc

I'm using VB.NET MVC 5.1 in VS2013 using Razor
siq.Price is a Decimal?
I'm trying to check if siq.Price has a value, and if so print it as a currency. I recieve this error when trying to access the .Value property for elements where true they returned true for .HasValue:
Nullable object must have a value.
Description: An unhandled exception occurred during the execution of the current web request.
Please review the stack trace for more information about the error and
where it originated in the code.
Exception Details: System.InvalidOperationException: Nullable object
must have a value.
I tried both of these lines of code, believing they should work without issue, yet recieved the error above:
#IIf(siq.Price.HasValue, siq.Price.Value, "N/A")
'and
#IIf(siq.Price.HasValue, siq.Price.Value.ToString("C"), "N/A")
As soon as I remove the .Value from the TruePart then it started working:
#IIf(siq.Price.HasValue, siq.Price, "N/A")
'and
#IIf(siq.Price.HasValue, String.Format("{0:C}", siq.Price), "N/A")
Can anyone explain why this is happening?! I'm rather perplexed.
NOTE: This piece of code works on it's own if the Price has a value, but not in the IIf():
#siq.Price.Value.ToString("C")

The IIF() function in VB.Net always evaluates both the true and false parts. Instead, you should change to use the IF() operator, which only evaluates the return value, so something like:
#If(siq.Price.HasValue, siq.Price.Value.ToString("C"), "N/A")

At first glance, VB.NET's IIf method seems equivalent to C#'s ternary operator (?:), but there's a big difference: because it's a method, not an operator, there's no short circuiting, and both parameters are always evaluated before being passed to the method.
What this means is that regardless of whether HasValue is true, both siq.Price.Value and "N/A" are evaluated, leading to the exception you saw.

IIf() runs both the true and false code. VB's conditional If operator is short-circuit so you can now safely write the following,
which is not possible using the IIf function:
Dim len = If(text Is Nothing, 0, text.Length)

Related

How does null assertion work in dart and when can I use it?

Can someone simply explain to me how null assertion (!) works and when to use it?
The ! operator can be used after any expression, e!.
That evaluates the expression e to value v, then checks whether v is the null value. If it is null, an error is thrown. If not, then e! also evaluates to v.
The static type of an expression e! is (basically) the static type of e with any trailing ?s remove. So, if e has type int?, the type of e! is int.
You should not use e! unless e can be null (the type of e is potentially nullable).
The ! operator is dynamically checked. It can throw at runtime, and there is no static check which can guarantee that it won't. It's like using a value with type dynamic in that all the responsibility of preventing it from throwing is on the author, the compiler can't help you, and you need good tests to ensure that it won't throw when it's not supposed to.
It's called an assertion because it should never throw in production code.
So, use e! when you know (for some reason not obvious to the compiler, perhaps because of some invariant guaranteeing that the value is not null while something else is true) that e is not null.
Example:
abstract class Box<T extends Object> {
bool hasValue;
T? get value;
}
...
Box<int> box = ...;
if (box.hasValue) {
var value = box.value!;
... use value ...
}
If you are repeatedly using ! on the same expression, do consider whether it's more efficient to read it into a local variable just once.
Also, if (like this Box example) the value being null is equivalent to the other test you just did, maybe just check that directly:
Box<int> box = ...;
var value = box.value;
if (value != null) {
... use value ...
}
This code, with an explicit != null check on a local variable, is statically guaranteed to not throw because the value is null.
The code using ! above relies on the author to maintain whichever invariant allowed them to write the !, and if something changes, the code might just start throwing at runtime. You can't tell whether it's safe just by looking at the code locally.
Use ! sparingly, just like the dynamic type and late declarations, because they're ways to side-step the compiler's static checking and ensure it that "this is going to be fine". That's a great feature when you need it, but it's a risk if you use it unnecessarily.

Null safety type promotion when assigning non-null value literal

In nullsafety.dartpad.dev if I write the following code:
void main() {
String? name = 'Bob';
print(name.length);
}
I get the following compile-time error:
An expression whose value can be 'null' must be null-checked before it can be dereferenced
And the following runtime error:
Property 'length' cannot be accessed on 'String?' because it is potentially null.
The Type promotion on null checks documentation says:
The language is also smarter about what kinds of expressions cause promotion. An explicit == null or != null of course works. But explicit casts using as, or assignments, or the postfix ! operator we’ll get to soon also cause promotion. The general goal is that if the code is dynamically correct and it’s reasonable to figure that out statically, the analysis should be clever enough to do so.
Question
There is no possible way name could be null in the code above. The documentation also says assignments should cause type promotion. Am I misunderstanding type promotion or is this a bug in DartPad?
Clarification
Since a couple of the answers are providing workaround solutions to the error messages, I should clarify that I'm not trying to solve the coding problem above. Rather, I'm saying that I think the code should work as it it. But it doesn't. Why not?
This answer is in response to the bounty that was added to the original question. The bounty reads:
Please explain how String? is different from String and how type
promotion works in Dart.
String? vs String
The type String? can contain a string or null. Here are some examples:
String? string1 = 'Hello world';
String? string2 = 'I ❤️ Dart';
String? string3 = '';
String? string4 = null;
The type String, on the other hand, can only contains strings (once null safety is a part of Dart, that is). It can't contain null. Here are some examples:
String string1 = 'Hello world';
String string2 = 'I ❤️ Dart';
String string3 = '';
If you try to do the following:
String string4 = null;
You'll get the compile-time error:
A value of type 'Null' can't be assigned to a variable of type 'String'.
The String type can't be null any more than it could be an int like 3 or a bool like true. This is what null safety is all about. If you have a variable whose type is String, you are guaranteed that the variable will never be null.
How type promotion works
If the compiler can logically determine that a nullable type (like String?) will never be null, then it converts (or promotes) the type to its non-nullable counterpart (like String).
Here is an example where this is true:
void printNameLength(String? name) {
if (name == null) {
return;
}
print(name.length);
}
Although the parameter name is nullable, if it actually is null then the function returns early. By the time you get to name.length, the compiler knows for certain that name cannot be null. So the compiler promotes name from String? to String. The expression name.length will never cause a crash.
A similar example is here:
String? name;
name = 'Bob';
print(name.length);
Although name is nullable here, too, the string literal 'Bob' is obviously non-null. This also causes name to be promoted to a non-nullable String.
The original question was regarding the following:
String? name = 'Bob';
print(name.length);
It seems that this should also promote name to a non-nullable String, but it didn't. As #lrn (a Google engineer) pointed out in the comments, though, this is a bug and when null safety comes out, this will also work like the previous example. That is, name will be promoted to a non-nullable String.
Further reading
Sound null safety
Type promotion on null checks
I understand what you are saying. Try this out.
In order for type promotion to work you must first confirm that the value is not null as the documentation says.
As you can see in the picture dart is able to do the type promotion or understand that name is not going to be null because it checks that on the if statement beforehand.
But if using it outside the if statement without checking if it is not null beforehand, dart knows it can be assigned null anytime again. That’s why it encourages always checking if it is null. Because any instatiated variable ( a variable with a value assigned) can be assigned null in the future.

Grails wrong evaluation of expression

I wrote a function in my service class where I evaluate a passed parameters from controller but Grails is returning wrong evaluation results.
def list(String q,String qval,String srt,String ord){
log.debug("q==="+q)
log.debug("qval==="+qval)
log.debug("srt==="+srt)
log.debug("order==="+ord)
all these debug statements print null as expected. Now
boolean qvalbool=qval?.trim()
log.debug("qvalbool===>>"+qvalbool) prints true!!!
!StringUtils.isEmpty(q) && !StringUtils.isEmpty(qval) returns true!!
both statements should return false while they are returning true what is going on with this? any ideas?
I'm using grails 2.4.2
Evan Wong's comment is very likely correct that you're seeing a string containing the word null.
Often when Groovy prints out values it's not apparent what their type is.
groovy:000> null
===> null
groovy:000> 'null'
===> null
Also in Groovy the expression null + '' evaluates to the String 'null'.
That would be an easy way to change the value of this parameter so it contains the string 'null'.

Spark null operator not working with nullable types

I have a nullable DateTime I want to show in ShortDate format if it has a value, but I can't get it right. I am trying to use the null operator ($!{}) here.
It should work like this:
<td>$!{period.Enddate.Value.ToShortDateString()}</td>
But this gives an InvalidOperationException: nullable object must have a value.
Removing the 'Value' part won't work either, that will give the obvious 'System.Nullable has no definition for ToShortDateString' message.
With the conditional operator it works fine, but that one only works for attributes like this:
<td value="$!{period.Enddate.Value.ToShortDateString()}?{period.Enddate.HasValue}"></td>
And I am trying to get it inside the td element, not as an attribute for td.
Am I doing something wrong here, or is this a known issue?
I understand that catching an InvalidOperationException (thrown by the Nullable class) is trickier than catching a NullReferenceException, but I think it is a serious flaw.
Cheers,
Ronald
As of Spark v1.6, here are some options:
use a format specfier -
<td>${ string.Format("{0:M/dd/yy}", period.Enddate) }</td>
or create an additional presentation property -
public string EnddateText
{
get
{
var result = Enddate.HasValue ? Enddate.Value.ToShortDateString() : string.Empty;
return result;
}
}
<td>${ period.EnddateText }</td>

F# string operator blows up on guids

I was under impression that in F# the following two lines are supposed to give identical results:
let a = string v
let a = v.ToString()
It is implied that v is an object. It turns out that if v is a System.Guid the first line just throws an exception:
System.FormatException occurred
Message="Format String can be only \"D\", \"d\", \"N\", \"n\", \"P\", \"p\", \"B\" or \"b\"."
Source="mscorlib"
StackTrace:
at System.Guid.ToString(String format, IFormatProvider provider)
InnerException:
I can certainly deal with Guids separately, the question is what other objects will give me the same trouble? Should I avoid using the string operator at all?
In my case the object potentially can be anything
This is a bug that is (will be) fixed in the next release.
(In general, it should work; the bug is because System.Guid does not respond to the IFormattable "G" specifier, despite the fact that the docs for IFormattable say that all implementers must implement the "G" specifier. So it's actually kinda a bug in System.Guid, but the F# library will work around this bug in its 'string' operator in the next release.
In short, you can use this operator safely, except for Guid right now, but that will be fixed soon. In the meantime you can special-case Guid.)

Resources