Another bug ?? If() function this time...http://forums.asp.net/t/1687066.aspx/1?Another+bug+If+function+this+time+Thu, 09 Jun 2011 22:16:51 -040016870664447093http://forums.asp.net/p/1687066/4447093.aspx/1?Another+bug+If+function+this+time+Another bug ?? If() function this time... <p>I have nullable decimal variable.<br> I can assign null (nothing) to it.</p> <p>Everything works fine, until I try to assign null (nothing) to it from If() or IIf() functions!<br> Somehow tests done in aftermentioned functions return wrong logical result!</p> <p>Am I missing something??? i'm so tired by now, that it is possible :) help please!</p> <p></p> <pre class="prettyprint">&lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt; &lt;title&gt;&lt;/title&gt; &lt;meta charset=&quot;utf-8&quot; /&gt; &lt;/head&gt; &lt;body&gt; &lt;div&gt; @Code Dim dec As Decimal? = Nothing If dec Is Nothing Then ' works correctly @:Nothing Else @dec End If @&lt;br /&gt; Dim strx = &quot;&quot; dec = If(Len(strx) &gt; 0, strx.AsDecimal(), Nothing) If dec Is Nothing Then @:Nothing Else ' WHY this code goes here ??? dec should be nothing!!!!! @dec End If End Code &lt;/div&gt; &lt;/body&gt; &lt;/html&gt;</pre> 2011-06-06T11:47:22-04:004447135http://forums.asp.net/p/1687066/4447135.aspx/1?Re+Another+bug+If+function+this+time+Re: Another bug ?? If() function this time... <p>ha, I think I understood the reason of this - when returning result function &quot;If&quot; tries to convert it to the needed type.</p> <p>But it works incorrectly - it converts result to &quot;Decimal&quot; and not to &quot;Decimal?&quot;,<br> so &quot;Nothing&quot; is converted to decimal 0 and no error is thrown.. :)</p> 2011-06-06T12:09:58-04:004447137http://forums.asp.net/p/1687066/4447137.aspx/1?Re+Another+bug+If+function+this+time+Re: Another bug ?? If() function this time... <p>no, it's not the reason - if i use code:</p> <p>dec = If(Len(strx) &gt; 0, Nothing, Nothing)</p> <p>everything works as expected - dec is nothing..</p> <p></p> <p>quite enjoying talking to myself here... :)))</p> <p></p> <p>EDIT:&nbsp;dec = If(LHtml.fIsDecimal(strx), Nothing, Nothing) <strong>changed to</strong> dec = If(Len(strx) &gt; 0, Nothing, Nothing)</p> 2011-06-06T12:14:01-04:004447140http://forums.asp.net/p/1687066/4447140.aspx/1?Re+Another+bug+If+function+this+time+Re: Another bug ?? If() function this time... <p>It is because&nbsp; strx.AsDecimal() converts it to a decimal which is zero hence the reason why your code hits the other block</p> 2011-06-06T12:15:22-04:004447144http://forums.asp.net/p/1687066/4447144.aspx/1?Re+Another+bug+If+function+this+time+Re: Another bug ?? If() function this time... <p>i have ment</p> <p>dec = If(Len(strx) &gt; 0, Nothing, Nothing)</p> <p>in previous post..</p> 2011-06-06T12:17:08-04:004447148http://forums.asp.net/p/1687066/4447148.aspx/1?Re+Another+bug+If+function+this+time+Re: Another bug ?? If() function this time... <p>Jeev - thanx for answer, but i DO NOT convert anything before test is done:<br> first i check if string is not empty - if it is - i do not want to convert it to decimal - i want to return null (nothing)<br> and then insert this value into database, so my nullable column will have null value instead of 0 (zero).</p> <p></p> <p>if i do check like so:</p> <p>dim dec as decimal? = if(str.length()&gt;0,str.asdecimal(),nothing)</p> <p>it does NOT work</p> <p></p> <p>if i do check like so:</p> <p>dim dec as decimal?<br> if str.length()&gt;0 then dec=str.asdecimal() else dec=nothing</p> <p>everything works fine...</p> <p></p> <p>:((((((( cannot trust If function anymore..</p> <p></p> 2011-06-06T12:23:23-04:004447406http://forums.asp.net/p/1687066/4447406.aspx/1?Re+Another+bug+If+function+this+time+Re: Another bug ?? If() function this time... <p></p> <blockquote><span class="icon-blockquote"></span> <h4>trolis</h4> dim dec as decimal? = if(str.length()&gt;0,str.asdecimal(),nothing)</blockquote> <p></p> <p>IF vs IIF</p> <p><span style="text-decoration:line-through">IF short circuits - you never get to assigning &quot;nothing&quot; to your nullable type. Once it hits str.asdecimal(), you have in fact assigned a value to to your nullable type.</span></p> <p>IIF should work - just make sure that's what you want. Both true and false are evaluated so:</p> <pre class="prettyprint">Dim d As Decimal? = IIf(str.Length &gt; 0, str.AsDecimal(), Nothing)</pre> <p>Edit:</p> <p>My big mistake, short circuit has nothing to do with it. Mea culpa.</p> <p>IIF returns object (nothing = nothing), while IF returns value (default value of decimal is 0)</p> 2011-06-06T15:42:26-04:004447741http://forums.asp.net/p/1687066/4447741.aspx/1?Re+Another+bug+If+function+this+time+Re: Another bug ?? If() function this time... <p>EdSF - yes, that is the answer that i was looking for :) this was one of my versions, why this is happening.</p> <p>It's sad - because i'm now stuck with slower function (or more code)...</p> <p>when you posted your answer before edit, i haven't really understood what you've meant.</p> <p>so i began to write console test application :)</p> <p></p> <pre class="prettyprint">Module Module1 Function f1() As String Console.WriteLine(&quot;f1&quot;) Return &quot;return from f1&quot; End Function Function f2() As String Console.WriteLine(&quot;f2&quot;) Return &quot;return from f2&quot; End Function Sub Main() Dim str = &quot;&quot; Console.WriteLine(If(str.Length &gt; 0, f1, f2)) Console.WriteLine(IIf(str.Length &gt; 0, f1, f2)) Console.WriteLine(&quot;-------&quot;) Dim dec As Decimal? dec = If(str.Length &gt; 0, f1, Nothing) If dec Is Nothing Then Console.WriteLine(&quot;Nothing&quot;) Else Console.WriteLine(dec) Console.WriteLine(&quot;-------&quot;) dec = IIf(str.Length &gt; 0, f1, Nothing) If dec Is Nothing Then Console.WriteLine(&quot;Nothing&quot;) Else Console.WriteLine(dec) End Sub End Module</pre> <p>anyway - thank you for clarification, i totally have thought, that IF and IIF have only one difference - speed.</p> <p></p> <p>P.S. it's interesting though, why IF returns nothing in this case: IF(str.length&gt;0, nothing, nothing) and does not convert nothing to decimal 0D.</p> 2011-06-06T20:54:59-04:004447839http://forums.asp.net/p/1687066/4447839.aspx/1?Re+Another+bug+If+function+this+time+Re: Another bug ?? If() function this time... <p></p> <blockquote><span class="icon-blockquote"></span> <h4>trolis</h4> IF returns nothing in this case: IF(str.length&gt;0, nothing, nothing)</blockquote> &nbsp; <p></p> <p>Ok, I took a trip on that one......I can't find any reference to that except <strong> possibly</strong> this blog post:<br> <a href="http://blogs.msdn.com/b/vbteam/archive/2008/03/11/if-operator-a-new-and-improved-iif-sophia-salim.aspx">http://blogs.msdn.com/b/vbteam/archive/2008/03/11/if-operator-a-new-and-improved-iif-sophia-salim.aspx</a></p> <p>Note the note:&nbsp;<br> <strong>TruePart, </strong>is the return value of the IF operator if the test expression above evaluates to true. <span style="color:red">Note that the return <strong>type</strong> of the operator is decided based on the wider of the types of the truepart and the falsepart, e.g, if the truepart is an integer and the falsepart is a decimal, then decimal which is the wider of the two types will be the return value's type. For details on type conversions and for a list of wider and narrower types</span>, please <a title="refer here" href="http://msdn2.microsoft.com/en-us/library/k1e94s7e(VS.80).aspx" target="_blank"> refer here</a></p> <p>Nothing (true part) vs Nothing (false part) = nothing (object)?</p> <p>Unsure why the note is written in such a way that it it seems to refer only to the True part (the statement does say &quot;the return type of the operator&quot;).....but it's a blog post....why it doesn't seem document/explained/noted anywhere else is another mystery....at least I can't find it in docs.....or perhaps missed it....</p> <p>Anybody from MS care to comment on this?</p> <p>Great thread!</p> <p>&nbsp;</p> <p>&nbsp;</p> 2011-06-06T22:56:00-04:004448134http://forums.asp.net/p/1687066/4448134.aspx/1?Re+Another+bug+If+function+this+time+Re: Another bug ?? If() function this time... <p>BTW. when using IF as coalesce, it works as expected:</p> <p></p> <pre class="prettyprint">dim dec as decimal? = nothing dim result as decimal? = 5D result = IF(dec, nothing) 'result is now nothing...</pre> <p></p> <p>there is question in that blog post:</p> <p></p> <blockquote><span class="icon-blockquote"></span>For those addicted IIF users wondering if they can still use the legacy IIF function in Orcas, the answer is <strong>yes. </strong>We still support IIF, but with all the amazing things that you can do with the <strong>IF operator, </strong>why would you want to keep on typing those extra &quot;i&quot;s?</blockquote> <p></p> <p>the answer to this question is in this thread :)</p> <p></p> <p>EdSF - also, as you have said, in that blog post there are the lines:</p> <p></p> <blockquote><span class="icon-blockquote"></span>Note that the return <strong>type</strong> of the operator is decided based on the wider of the types of the truepart and the falsepart, e.g, if the truepart is an integer and the falsepart is a decimal, then decimal which is the wider of the two types will be the return value's type</blockquote> <p></p> <p>So, if we have:</p> <p>IF(str.length&gt;0,str.AsDecimal(),nothing)</p> <p>I think that &quot;Nothing&quot; is wider - it's Object and Object is the widest type in .net ?</p> <p></p> <p>P.S. it may be not BUG, this behavior may be by design, but still - for me it's counter intuitive..</p> <p></p> 2011-06-07T06:06:46-04:004451273http://forums.asp.net/p/1687066/4451273.aspx/1?Re+Another+bug+If+function+this+time+Re: Another bug ?? If() function this time... <p>I'm Lucian Wischik, the VB specification lead, and I re-implemented the &quot;If(,,)&quot; and &quot;If(,)&quot; operators in VS2010, so here's a definitive answer:</p> <p>&nbsp;</p> <p>It's important to note that &quot;Nothing&quot;&nbsp;in VB does <em>NOT</em> mean &quot;null&quot;. Instead it means &quot;default<em>(type)</em>&quot;, i.e. the default value of the type in question. This is what lead to the problem in this thread. It's something we don't like in the language, and have been trying to figure out how to improve, but we haven't yet figured out a good answer:<br> <a href="http://blogs.msdn.com/b/lucian/archive/2010/03/05/req24-warnings-where-nothing-isn-t-null.aspx">http://blogs.msdn.com/b/lucian/archive/2010/03/05/req24-warnings-where-nothing-isn-t-null.aspx</a></p> <p>&nbsp;</p> <p>Oh, and to get the answer first, here's how I'd have written the code in question:</p> <pre class="prettyprint">dec = If( strx.IsNullOrEmpty(), CType(Nothing, Decimal?), str.AsDecimal())</pre> <p>&nbsp;</p> <p>The behavior is&nbsp;explained in the VB language specification, found in &quot;C:\Program Files (x86)\Microsoft Visual Studio 10.0\VB\Specifications\1033&quot;, section &#36;11.22, although I'm afraid that the language of the spec is a bit confusing.</p> <ul> <li>Always remember&nbsp;that &quot;<strong>Nothing</strong>&quot; just means &quot;default(<em>type</em>)&quot; for whatever type is expected. For example: <ul> <li>&quot;Dim x As Integer = Nothing&quot; will make x be the default integer 0 </li><li>&quot;Dim x As Integer? = Nothing&quot; will make x be the default <em>nullable</em>, i.e. a NULL&nbsp;value of type Integer?. </li></ul> </li><li>The type of <strong>If(b,TruePart,FalsePart)</strong> is inferred to be the <em> dominant type</em> of TruePart and FalsePart. <ul> <li>&quot;Nothing&quot; doesn't really have&nbsp;a type of its own. It doesn't contribute to the question of dominant type. </li><li>If we have the two expressions &quot;strx.AsDecimal()&quot; and &quot;Nothing&quot;, what is their dominant type? Well, Nothing doesn't contribute, so the dominant type is Decimal. </li><li>&quot;If(b, strx.AsDecimal(), Nothing)&quot; will pick DECIMAL as the dominant type, therefore. It will treat Nothing as the default value of Decimal, i.e. the decimal number 0. It will <em>NOT</em> treat Nothing as a nullable NULL. </li></ul> </li><li>Suggested code: &quot;<strong>If(b, strx.AsDecimal(), CType(Nothing,Decimal?))</strong>&quot; <ul> <li>This picks &quot;Decimal?&quot; as the dominant type. That's why it works. </li></ul> </li></ul> <p>&nbsp;</p> <p>So what about the other behavior that has been observed in this thread? Well, ...</p> <p>&nbsp;</p> <ul> <li>Dim x As Decimal? = IIf(b, strx.AsDecimal(), Nothing)... <ul> <li>The IIf runtime function (with two &quot;I&quot;s) casts both of its arguments as Object. In particular, Nothing will be a NULL pointer of type Object. If the condition ends up false, the result of IIf will be a NULL&nbsp;reference of type Object. This can be&nbsp;converted to Decimal?. The conversion involves a runtime check with slight additional perf overhead, and is counted as &quot;narrowing&quot;. </li></ul> </li><li>Dim x As Decimal? = If(b, Nothing, Nothing)... <ul> <li>Here the If operator has nothing at all to go on to help it find the dominant type. In these cases it just falls back to Object as the dominant type. So again, the result of If will be a NULL reference of type Object, which involves the runtime narrowing conversion. </li></ul> </li></ul> <p>&nbsp;</p> <p>I want to stress once again that &quot;Nothing&quot; doesn't necessarily have type Object. It will&nbsp;fall back to Object if it doesn't have anything else to go on. But if you do give it something else to go on, e.g. &quot;Dim x As String = Nothing&quot;, then it's not Object at all.</p> <p>&nbsp;</p> <p>&nbsp;</p> 2011-06-08T17:05:31-04:004453365http://forums.asp.net/p/1687066/4453365.aspx/1?Re+Another+bug+If+function+this+time+Re: Another bug ?? If() function this time... <p>wow, what a comprehensive answer! ok, I see the difference now, but that behavior is very un-intuitive :(<br> (also I doubt that there are many programmers who read VB language specification to learn the language)..</p> <p></p> <p></p> <blockquote><span class="icon-blockquote"></span>It's something we don't like in the language, and have been trying to figure out how to improve, but we haven't yet figured out a good answer:</blockquote> <p></p> <p>why not just add another keyword, lets say &quot;Null&quot;, that would behave like C# &quot;Null&quot;?<br> There is VBNull, but it behaves like Nothing as I understand.<br> Or add another vb option like &quot;NothingAsNull on&quot;, &quot;NothingAsNull off&quot;. And by default it would be &quot;off&quot; for compatibility ?<br> Yeah, I understand that it would be a mega-work, but maybe it is worth considering (just to make VB and C# closer)...</p> <p></p> <p>Anyway, big thanks for the answer Lucian :)</p> 2011-06-09T18:28:16-04:004453632http://forums.asp.net/p/1687066/4453632.aspx/1?Re+Another+bug+If+function+this+time+Re: Another bug ?? If() function this time... <p>This was an EXCELLENT thread! Bravo!</p> <p>Thanks for the question, and to Lucian for the succint answer - which&nbsp;should hopefully&nbsp;be in MSDN/VS Help&nbsp;documentation!</p> <ul> <li>IF - if you read the documenation, you'll only glean &quot;short circuiting&quot;, it doesn't include any of the details above </li><li>NOTHING - documentation does include the concept, just not explained as good as the above/Lucian's blog post (by example/gotchas) </li></ul> 2011-06-09T22:16:51-04:00