VB Conversion Keywords And .NET Conversion Routines

J

Jay B. Harlow [MVP - Outlook]

Scott,
Paul's blog indicates that CInt() is an alias for CType(, Integer).

As Cor suggests CType is the conversion operator, while DirectCast is the
cast operator.

To "confuse" the issue the Conversion operator can be used as the cast
operator, however I make every effort to avoid this, as VS.NET 2005 allows
operator overloading! With operator overloading we can use the Conversion
operator (CType) to convert our types as needed.

http://msdn2.microsoft.com/library/yf7b9sy7.aspx


For example we can define the conversion for a Rational (Fraction) type to &
from Double. Where the Rational type holds the Numerator & Denominator as
separate fields. CType will be able to use the overloaded conversion
operators, while I understand that Convert.To* will not.

Public Structure Rational

Private m_numerator As Integer
Private m_denominator As Integer

Public Shared Widening Operator CType(ByVal f As Rational) As Double
Return f.m_numerator / f.denominator
End Operator

Public Shared Narrowing Operator CType(ByVal d As Double) As Rational
Return New Rational(d)
End Operator

End Structure


Dim f As Fraction
Dim d As Double

f = CType(d, Fraction)
d = f

Hope this helps
Jay
 
B

Bob Grommes

I'm given to understand that CType() itself is in fact equivalent to the
corresponding Convert methods, and that DirectCast is about the same as a C#
cast, which is faster since it's a cast rather than a conversion.

In reality I'm not sure that we're doing anything but splitting hairs here
though ... this conversation is interesting but ultimately, in real world
line of business scenarios, the differences in performance are not that
significant. If we were doing matrix math or image manipulation, it might
matter. But if we're simply unboxing datarow values and converting textbox
strings to integer or decimal, and other *typical* operations, it probably
doesn't in fact matter how you accomplish it, from a performance
perspective. So I go for consistency and use metaphors that would be
familiar to any developer who knows the .NET framework, regardless of their
language experience.

--Bob
 
B

Bob Grommes

Whoops, that was misinformation, I misread an article -- CType() is exactly
equivalent to the corresponding intrinsic VB functions (CInt, etc) not to
Convert methods.
 
H

Herfried K. Wagner [MVP]

Scott M. said:
Well, I don't necessarily agree, in that with CType, there is just one
function to use. Rather than the 5 or 6 legacy conversion functions. I
find CType to be more consistent.

Why do you think the 'C*' conversion functions are "legacy functions"? They
are part of the Visual Basic language like 'If...Then'. There is
*absolutely no* reason for not using them. Or would you try to avoid to use
'(int)x' in C# because it's "legacy"?!
 
S

Scott M.

Well, I thought that I did explain why I prefer not to use them. I prefer
the consistency of CType, rather than the various C* functions. In my mind,
the many C* functions have been replaced by just one function to deal with.
In that sense, I can't imagine why anyone would want to use the various C*
functions.
 
B

Bob Grommes

"Legacy" is a matter of perspective. The C*() functions are not legacy VB
functions in the sense that they have been deprecated in the VB language,
but if you take a larger view from a .NET perspective, they are legacy
functions in that they duplicate .NET framework functionality for the sake
of backward compatibility support of a non .NET language. The C*()
functions have no reason to exist other than that, and in that sense they
make VB.NET needlessly different with a divergent syntax and in some cases,
different behaviors or responses to boundary conditions.

If you are developing in other .NET languages as well as VB.NET, the C*()
functions seem much more superfluous than if you come from a VB6 background
and are mostly focused on developing in VB.NET.

Mind you, I'm not asking you to agree or disagree, just to understand that
there are other points of view, and they have validity depending on your
perspective and approach.

--Bob
 
B

Bob Grommes

So what then is the difference between CType and the Convert methods?

The URLs that have been provided elsewhere in this thread explain it better
than I can, but basically, the Convert methods are the way the framework
expects conversions to happen. For example, Convert.ToInt32("2.5") is an
error, whereas CInt("2.5") or CType("2.5",Integer) is not. Furthermore,
CInt("2.5") yields 2 (banker's rounding) whereas Math.Round(2.5,0) yields 3.
I'm sure there are other examples. Personally I don't want to have to
remember special rules for a particular language.

On the plus side, some kinds of calls to the C*() functions are optimized to
be very fast, faster than Convert methods. Such as CInt(someLongValue) or
CLng(someIntValue). But in practice, how often do you actually do such
conversions? In my work, almost never. In any case the consensus in this
thread, with which I now agree, is that real world performance differences
are negligible. So it's probably more important to do what you want, and do
it consistently.

--Bob
 
S

Scott M.

I know you didn't ask for agreement or disagreement, but I wholeheartedly
agree and think that you couldn't have summed it up better Bob.


Bob Grommes said:
"Legacy" is a matter of perspective. The C*() functions are not legacy VB
functions in the sense that they have been deprecated in the VB language,
but if you take a larger view from a .NET perspective, they are legacy
functions in that they duplicate .NET framework functionality for the sake
of backward compatibility support of a non .NET language. The C*()
functions have no reason to exist other than that, and in that sense they
make VB.NET needlessly different with a divergent syntax and in some
cases, different behaviors or responses to boundary conditions.

If you are developing in other .NET languages as well as VB.NET, the C*()
functions seem much more superfluous than if you come from a VB6
background and are mostly focused on developing in VB.NET.

Mind you, I'm not asking you to agree or disagree, just to understand that
there are other points of view, and they have validity depending on your
perspective and approach.

--Bob
 
J

Jay B. Harlow [MVP - Outlook]

Bob,
Furthermore, CInt("2.5") yields 2 (banker's rounding) whereas
Math.Round(2.5,0) yields 3.
They both yield 2 in both VS.NET 2002 & VS.NET 2003 (.NET 1.0 SP3 & .NET 1.1
SP1). I would be very surprised if this changed in VS.NET 2005, I do however
understand that VS.NET 2005 gives us the option to use Banker's Rounding or
not.

In fact all three (CInt, Math.Round, Convert.ToInt16) do banker's rounding
as .NET does banker's rounding.

Try the following:
Debug.WriteLine(CInt(2.5), "CInt(2.5) ")
Debug.WriteLine(CInt("2.5"), "CInt(""2.5"")")
Debug.WriteLine(Convert.ToInt32(2.5), "Convert.ToInt32(2.5)")
Debug.WriteLine(Math.Round(2.5, 0), "Round(2.5)")
Debug.WriteLine(CInt(1.5), "CInt(1.5) ")
Debug.WriteLine(CInt("1.5"), "CInt(""1.5"")")
Debug.WriteLine(Convert.ToInt32(1.5), "Convert.ToInt32(1.5)")
Debug.WriteLine(Math.Round(1.5, 0), "Round(1.5)")

Hope this helps
Jay
 
H

Herfried K. Wagner [MVP]

Scott M. said:
Well, I thought that I did explain why I prefer not to use them. I prefer
the consistency of CType, rather than the various C* functions.

I prefer the readability of code that uses the various 'C*' functions :).
In my mind, the many C* functions have been replaced by
just one function to deal with.

The 'C*' functions were not replaced. Instead, 'CType' was added to allow
explicit casting to user defined types when using strict semantics.
 
H

Herfried K. Wagner [MVP]

Bob,

Bob Grommes said:
"Legacy" is a matter of perspective. The C*() functions are not legacy VB
functions in the sense that they have been deprecated in the VB language,
but if you take a larger view from a .NET perspective, they are legacy
functions in that they duplicate .NET framework functionality for the sake
of backward compatibility support of a non .NET language.

So '(int)', '(string)' etc. in C# are casts that should not be used because
they are included for backward compatibility reasons too? I feel sorry, but
I cannot follow this argumentation. There are /so many/ features in
VB.NET/C# that wrap around low-level features provided by the .NET
Framework. That does't make them bad features.
The C*() functions have no reason to exist other than that,
and in that sense they make VB.NET needlessly different with
a divergent syntax

Is 'Select Case' a legacy statement too? You could replace it by lots of
'If's. Isn't VB.NET/C# only a replacement for pure and clean MSIL?
If you are developing in other .NET languages as well as VB.NET, the C*()
functions seem much more superfluous than if you come from a VB6
background and are mostly focused on developing in VB.NET.

I am developing in C# too, but that /never/ lead me to think that 'CInt',
etc. are redundant. They are syntax shortcuts like the '+' operator, for
example. The can be used but there are alternatives. Nevertheless, I try
to pick the feature out of the set of semantically equivalent features that
are available by choosing the feature with the best readability and
maintainability. For me, it does not matter how easily code can be
converted to another .NET programming language, because this would reduce
productivity without adding any value.
Mind you, I'm not asking you to agree or disagree, just to understand that
there are other points of view, and they have validity depending on your
perspective and approach.

:)
 
S

Scott M.

Herifried, I don't think you really read my post. I'm not looking for an

and I simply told you why I prefer to not use them.
 
S

Scott M.

Herfried, take a deep breath. I think we are at the point in this thread
where it's pretty clear we are talking about preferences and you are trying
to "argue" your preference over others. If there was only one choice, then
there wouldn't be a need for preferences.

I say tom-A-to, you say to-MA-to.
 
H

Herfried K. Wagner [MVP]

Scott M. said:
Herifried, I don't think you really read my post. I'm not looking for an
argument.

Well, then I don't see any reason for discussion at all.
 
H

Herfried K. Wagner [MVP]

Scott M. said:
Herfried, take a deep breath. I think we are at the point in this thread
where it's pretty clear we are talking about preferences and you are
trying to "argue" your preference over others. If there was only one
choice, then there wouldn't be a need for preferences.

There are good and bad preferences. But I see, you don't like in-depth
discussion and evaluation of arguments.
 
G

Guest

What if in vb.Net 2007 an integer becomes 8 bytes and a double becomes 16
bytes, would not then Cint and Cdbl or Ctype maintain more consistency of
code and automatically utilize 8 byte integers as opposed to Convert.ToInt32?
In the 64bit world, this could become real confusing. Wonder how M'soft
will handle it?

Jay B. Harlow said:
rawCoder,
May b someone from Visual Basic Development team might be in the best
position to tell us ...
In case you missed it:

www.panopticoncentral.net is Paul Vick's blog, Paul Vick is the Technical
Lead of the Visual Basic.NET Development team at Microsoft, here is his
thoughts:

http://www.panopticoncentral.net/archive/2004/06/07/1200.aspx


Hope this helps
Jay


rawCoder said:
Thank you all for your comments.

Seems like the comments are a little diverse than i expected them to be
which might mean that the problem isnt that simple as it initially seemed
to
me. I hope I aint asking for too much but can someone please summarize (
if
possible ) the differences in terms of performance and IL generation for
the
followings.

Intrinsic VB Conversion Ops ( CInt, CBool, CDbl, CLng, CObj, CStr etc. )
Convert class Convert.To methods
CType method
DirectCast method

I understand that there are differences of ValueType and ReferenceType
and
the datatype diffreneces also count, but there must be some flow or
checklist to identify excatly when should one use which conversion
technique..

May b someone from Visual Basic Development team might be in the best
position to tell us which IL is better

( Dim i As Integer = CInt("1") )
IL_0001: ldstr "1"
IL_0006: call int32
[Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.IntegerType::F
romString(string)
IL_000b: stloc.0

( Dim j As Integer = CInt("2") )
IL_000c: ldstr "2"
IL_0011: call int32 [mscorlib]System.Convert::ToInt32(string)
IL_0016: stloc.1

Thank You Again All.
rawCoder
 
S

Scott M.

In depth discussion is fine and as I've said, it seems that we've played
that out as most of the last posts are now talking about how people prefer
this or that. Since the in depth discussion has pretty much resulted in a
consensus that for the most part using either syntax is equivalent, we are
now talking about preferences. If A = B then it is hard to say that A is
bad but B is good.
 
J

Jon Skeet [C# MVP]

Dennis said:
What if in vb.Net 2007 an integer becomes 8 bytes and a double becomes 16
bytes, would not then Cint and Cdbl or Ctype maintain more consistency of
code and automatically utilize 8 byte integers as opposed to Convert.ToInt32?
In the 64bit world, this could become real confusing. Wonder how M'soft
will handle it?

If that's the case, it's no longer a compatible language with the
existing VB.NET, basically.

Fortunately, I don't think MS is stupid enough to do that. There's
already an integer type which is 8 bytes long, and if they need to
introduce new, larger types, they can give them new names. That way we
won't get into the message C is in.
 
H

Herfried K. Wagner [MVP]

Dennis said:
What if in vb.Net 2007 an integer becomes 8 bytes and a double becomes 16
bytes, would not then Cint and Cdbl or Ctype maintain more consistency of
code and automatically utilize 8 byte integers as opposed to
Convert.ToInt32?
In the 64bit world, this could become real confusing. Wonder how M'soft
will handle it?

The datatypes will remain in their current size, which means that an
'Integer' (= 'Int32') will /always/ be 32-bit, and 'Integer' will /always/
map to 'Int32'.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top