Boolean True
conversion to any signed numeric type produces -1
, and to any unsigned, the maximum value for this type, whereas there is no such conversion in C #. However, the Convert.ToInt32
method, for example, converts True
to 1
, and this is how it is most often represented in IL
. In the opposite direction, any number other than 0
is converted to True
.-1
to 1
is that the bitwise negative 0 (all bits are set to 0) is -1
in any language (all bits are set to 1
), so using this value combines logical and bitwise operations like And
, Or
and Xor
.Enum
types rather as a set of named constants of basic integer type. The place where this is most obvious is equality. It is always permissible to compare any integer with the enumeration value, whereas in C # this gives an error.SyntaxKind
enumeration was SyntaxKind
, which tells you which syntax the node represents (for example, IfStatement
, TryCastExpression
). One day, a developer used an API that tried to disengage from the language and returned one of the SyntaxKind
values, but only as an Integer
, and without receiving an error when comparing the raw Integer
and SyntaxKind
, this developer immediately came to my office and complained: “int is implementation detail, I should have been forced to make a ghost! " .Property Kind As SyntaxKind
) that pointed to the language-specific type, and all APIs started to return Integer
. All C # code broke, and all VB code continued to work as if nothing had happened.RawKind
and add language-specific extension methods Kind()
. All the C # code broke because the parentheses were needed to call the methods, but since they are not needed in VB, the entire VB code again continued to work as if nothing had happened.Byte
can represent values from 0 to 255. So, what happens when you add Byte
1 to Byte
255? If overflow / underflow is disabled, the value scrolls to 0. If the type is signed, it scrolls to the lowest negative number (for example, -128 for SByte
). This most likely indicates an error in your program. If overflow / underflow checking is enabled, an exception is thrown. To understand what I mean, take a look at this harmless For
loop. Module Program Sub Main() For i As Byte = 0 To 255 Console.WriteLine(i) Next End Sub End Module
Byte
boundary. But with the overflow check turned off, it loops because after 255 i becomes 0 again.Byte
. If you fold them, the answer will be 280, which does not fit into Byte. But your processor perceives it is not. Instead, he reports that the answer is 24.PositiveInfinity
, NegativeInfinity
, NaN
Single
or Double
to Decimal
values will throw an exception, since none of these values can in principle be represented in Decimal. CInt(CObj(Nothing)) = 0
CInt(Nothing) = 0
, and the language tends to be somewhat consistent, regardless of whether you typed your variables or not. This applies to any structure, not just built-in significant types. See the rationale at # 25 for more details.Short
to Integer
, but what if you try to convert packed Short
to Integer
? In VB Short
will be unpacked first and then converted to an Integer
. In C #, if you do not manually decompress short before converting to an int
, an InvalidCastException
will be thrown.String
and Char
String
converted to a Char
representing its first character.Char
converted to String
only reasonable way.String
and Char
arrayString
converted to a Char
array, consisting of all its characters.Char
array is converted to a String
consisting of all its elements.String
.ParamArray
modifier to the second overload parameter String.Join
, which accepts an array of strings . The exact preconditions are lost in time (probably for the better), but, as I believe, the reason is that with the ParamArray
modifier you can now convert the Char
array into a string and pass it as a separate element to the parameter array. A fun theme.CInt("&HFF") = 255
CInt("1e6") = 1_000_000
CDate("#12/31/1999#") = #12/31/1999#
CInt("&H" & input)
. Unfortunately, this symmetry is degrading at the time of this writing, because the VB runtime has not been updated to support the binary prefix & B or the digit 1_000
, but I hope this will be fixed in the next version. Scientific notation works, but without type suffixes, and date conversions also support standard date formats, so the JSON format used in ISO-8601 also works: CDate("2012-03-19T07: 22Z") = #3/19/2012 02:22:00 AM#
.Char
and integer typesChar
and Integer
are prohibited:CInt("A"c)
not compiled.CChar(1)
not compiled.CInt("1")
I think half of the readers would expect the number 1 (character value 1), and half would expect the number 49 (ASCII / UTF code for character 1). Instead of making the wrong choice in half the cases, VB has special functions for converting characters to ASCII / Unicode codes and vice versa, AscW
and ChrW
respectively.Nothing
in VB does not mean null . It means “the default value for the type for which it is used,” and it just so happens that for reference types, the default value is null. The difference matters only when used in a context in which: Module Program Sub Main() Dim i As Integer = 0 If i = Nothing Then Console.WriteLine("True") End If End Sub End Module
Integer (0)
with the default value of its type (also 0). The problem occurs in VB2005 / 2008 when you add nullable meaningful types. Take a look at this example: Module Program Sub Main() Dim i = If(False, 1, Nothing) End Sub End Module
i
is an Integer?
( Nullable(Of Integer)
). But this is not the case, because Nothing
gets the type out of context, and the only type in this context comes from the second operand, and this is a simple non-nullable Integer
(technically, Nothing
never has a type). Another way to look at this problem is the following example: Module Program Sub Main() M(Nothing) End Sub Sub M(i As Integer) Console.WriteLine("Non-nullable") End Sub Sub M(i As Integer?) Console.WriteLine("Nullable") End Sub End Module
Nothing
adds a “nullable” hint and that the language will choose an overload that accepts nullable
, but it does not (selects non-nullable
because it is “most specific”). At a minimum, it can be assumed that, like null in C #, the expression Nothing
does not apply to Integer
, and that the nullable overload will be chosen by the elimination method, but this is again based on the incorrect thought that Nothing = null (Is null?)
.Nothing
in VB. If you rewrite all three examples above in C # using default
instead of null
, you will get exactly the same behavior .Nothing
converted to a significant type and it is not null
in a nullable
significant type.Nothing
to 0
, 0.0
, ChrW(0)
, False
, #1/1/0001 12:00:00 AM#
ChrW(0)
#1/1/0001 12:00:00 AM#
or New T
(the default value for any structure) each time its value in runtime will be one of listed above.Null
or Nothing?
If(False, 0?, Nothing)
If (False, CInt? (0), Nothing)
Nothing
(the default value in a specific context), and in C # it is only null
.default(T)
(the default value of type T
), because newly added generics create a situation where you need to initialize a value, but you don’t know if it is a reference type or meaningful; VB does not do anything, because this script is already closed Nothing
.default
( default
value in context), since there are many scripts in which specifying T
redundant or impossibleNull
(or equivalent) expression because:Nothing?
); Imagine talking loudly about Nothing
and Nothing?
to explain something to a person.Nothing?
).Nothing
, and this function will be completely redundant most of the time.Nothing
obsolete for most scenarios.Nothing
and Null
will still behave the same at runtime for late binding, transforms, etc. Module Program Sub Main() Dim i As Integer? = If(False, 1, Nothing) Console.WriteLine(i) End Sub End Module
Dim i as Integer? = If(False, 1, Nothing)
Dim i as Integer? = If(False, 1, Nothing)
behaves the same as Dim i As Integer? : If False Then i = 1 Else i = Nothing
Dim i As Integer? : If False Then i = 1 Else i = Nothing
. In this case, this is not the case because the conditional expression (If)
does not “flow” (flow through) finite-type information to its operands. It turns out that it breaks all expressions in VB that rely on what is called finite (contextual) typing ( Nothing
, AddressOf
, an array of literals, lambda expressions, and interpolated strings) with problems ranging from non-compilability in general to silently creating incorrect values and to loud throwing exceptions. Here is an example of a non-compiled version: Module Program Sub Main() Dim i As Integer? = If(False, 1, Nothing) Console.WriteLine(i) Dim operation As Func(Of Integer, Integer, Integer) = If(True, AddressOf Add, AddressOf Subtract) End Sub Function Add(left As Integer, right As Integer) As Integer Return left + right End Function Function Subtract(left As Integer, right As Integer) As Integer Return left - right End Function End Module
If
statement that it cannot determine the type of the expression when both AddressOf
expressions AddressOf
intended to receive Func(Of Integer, Integer, Integer)
delegates Func(Of Integer, Integer, Integer)
.Nothing
null (), Nothing
nullability
() If(,,)
Nothing
( ) () — , . Module Program Sub Main() Dim i As Integer = 3 M((i)) Console.WriteLine(i) End Sub Sub M(ByRef variable As Integer) variable = -variable End Sub End Module
M(3)
, M(i)
, i
, . C# ( ) , M .((a + b) * c a + (b * c))
. , C#, C++, , , , . : « VB?» « C#?» source.roslyn.io — BoundParenthesized
VB C#. , , .Me
—Me
. , - , — , Me Structure . Me . C# this
, this
. Class C Sub M() Extension() End Sub End Class Module Program Sub Main() End Sub <Runtime.CompilerServices.Extension> Sub Extension(c As C) End Sub End Module
this.Extension()
.'Me.'
, , , , . VB.NET . , .Imports System.Console
WriteLine()
. 2015 C# . VB Shared- , System.Console
System.Diagnostics.Debug
, WriteLine
, . C# , , .System
System.Windows.Forms
— , , System
System.Windows
System.Windows
System.Windows.Forms
.System
Windows
, Windows
Form
.using
C# .System
, System
, System
. , . , ExtensionAttribute
, <Runtime.CompilerServices.Extension>
<System.Runtime.CompilerServices.Extension>
.using System
System.Threading
Threading
.System
, System.Threading
Threading
. , , , , .Imports
/ using
, C# using , , using .System
ComponentModel
System.Windows.Forms
ComponentModel
? ComponentModel
. , ComponentModel.PropertyChangedEventArgs
, ( , ). System.Windows.Forms
(, , , , ), (ambiguity errors).System
System.Windows.Forms
ComponentModel
, , System.ComponentModel
System.Windows.Forms.ComponentModel
, . , , , , . , , , .. ComponentModel.PropertyChangedEventArgs
System.ComponentModel.PropertyChangedEventArgs
, System.Windows.Forms.ComponentModel.PropertyChangedEventArgs
. , .Windows
, ( ) ( ) ( ). WinForms/WPF
UWP
. Class Contact Property Name As String Property FavoriteFood As String End Class Module Program Sub Main() Dim contacts = New List(Of Contact) From { {"Leo", "Chocolate"}, {"Donnie", "Bananas"}, {"Raph", "The Blood of his Enemies"}, {"Mikey", "Pizza"} } End Sub <Runtime.CompilerServices.Extension> Sub Add(collection As ICollection(Of Contact), name As String, favoriteFood As String) collection.Add(New Contact With {.Name = name, .FavoriteFood = favoriteFood}) End Sub End Module
Dim buffer(expression) As Byte
Dim buffer = New Byte(expression) {}
expression + 1
.DIM
( dimension — ). , , , : 0 expression. Microsoft BASIC 1 ( , 1984), ( ), 2002 .buffer(10)
0 10, 9!CType({1, 2, 3}, Short())
CType(New Integer() {1, 2, 3}, Short ())
, Integer
Short
.CType({1, 2, 3}, Short())
New Short() {1, 2, 3}
. No spoons.Dim empty As Integer() = {}
Dim array As Predicate(Of Char)() = {AddressOf Char.IsUpper, AddressOf Char.IsLower, AddressOf Char.IsWhitespace}
Dim byteOrderMark As Byte() = {&HEF, &HBB, &HBF} '
.IList(Of T)
, IReadOnlyList(Of T)
, ICollection(Of T)
, IReadOnlyCollection(Of T)
IEnumerable(Of T)
, , , ParamArray IEnumerable
.CType
:Long
Integer
(. «»);CTypeDynamic
).DirectCast
:Integer Byte
);(Type)expression
:CType
C# , . , . VB C# , IL . , C#, , . .CType
, (, ). CType
, DirectCast
, . , , IL : Object
( ValueType
) CLR «unbox» VB-, , (, Short
Integer
). , , C#. . , .5 Mod 2 * 3
5 VB, «» C# 5 % 2 * 3
3.String
:INumeric
).Math.Pow
Math.Pow
. , . , ( custom
) ( , System.Numerics.BigInteger
).op_Exponent
op_Exponentiation
. F# Pow
. . , .Is/IsNot
) .Option Compare Binary
Option Compare Text
. Option Compare Binary
, , VS.Select Case: Select Case “A” : Case “a”
Equals: “A”.Equals(“a”)
Contains: ”A”.Contains(“a”)
Distinct: From s In {“A”, “a”} Distinct
Option Compare
, «Empty». Module Program Sub Main() Dim s As String = Nothing If s = "" Then Console.WriteLine("Empty") End If End Sub End Module
String.IsNullOrEmpty(s)
.Option Compare Text
, , . , , .String
"". , VB String
. VB, Left
Mid
, String
. null . Len(CStr(Nothing)) = 0
Left(CStr(Nothing)
, 5) = ""
, CStr(Nothing).Length
CStr(Nothing).Trim()
.?
. ( )."String A" = "String B"
, Microsoft.VisualBasic.CompilerServices.Operators.CompareString
, - , , . LINQ- . , VB ( ). , , - , . LINQ-to-SQL, LINQ-to-Entities , Microsoft. , VB , !Option Compare
VB, InStr.Replace
Microsoft.VisualBasic.Strings
. , ?"?."
: obj?.Property obj
null, null, .Is/IsNot
, Boolean?
bool
bool?
Boolean
= Boolean?
, True
, False
null
. . C# non-nullable bool
, .(if (value == null))
. VB , VB (=/<>) (Is/IsNot)
, VB Is Nothing
non-nullable Boolean
.And/AndAlso
Or/OrElse
.Integer?
( ), VB, C# null, :Boolean?
, VB .True/False
, , null. , AndAlso
OrElse
.nullable boolean (bool?)
. , , non-nullable boolean nullable boolean . Imports System.ComponentModel Class BindableRange Implements INotifyPropertyChanged Property _EndDate As Date? Property EndDate As Date? Get Return _EndDate End Get Set(value As Date?) ' This line here: If value = _EndDate Then Return _EndDate = value RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(NameOf(EndDate))) End Set End Property Public Event PropertyChanged As PropertyChangedEventHandler _ Implements INotifyPropertyChanged.PropertyChanged End Class Module Program WithEvents Range As New BindableRange Sub Main() Range.EndDate = Today Range.EndDate = Today Range.EndDate = Nothing Range.EndDate = Nothing End Sub Private Sub BindableRange_PropertyChanged(sender As Object, e As PropertyChangedEventArgs) _ Handles Range.PropertyChanged Console.WriteLine(e.PropertyName & " changed.") End Sub End Module
EndDate
, , , Nothing
. If value <> _EndDate Then _EndDate = value RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(NameOf(EndDate))) End If
If value Is Nothing AndAlso _EndDate Is Nothing Then Return If value <> _EndDate Then Return
Optional(Of T)
, , , null, , .WHERE Column = NULL
. , , OFF ( ). SQL Server ( ) . : « ? . , - Option ANSI_NULLS Off VB.NET?» . :() => expression
C# Function() expression
VB. Function()
-, - , VB. a = b
, a
b
( Boolean
), b
. - (delegate relaxation) VB ( -) Sub- ( ). . () => a = b
C# VB — Sub() a = b
. — - , .Sub
-) , ( Function
-) .Async Function
async void
async
-, , , Task
void
, , Task
, .void Async
Async Sub
, Task
Task(Of T)
— Async Function
. , , VB, (relaxing) Task Async
void
. Async Sub
, , . Class Foo 'Function [Select](Of T)(selector As Func(Of String, T)) As Foo ' Return Me 'End Function Function Where(predicate As Func(Of String, Boolean)) As Integer Return 0 End Function End Class Module Program Sub Main() Dim c As New Foo Dim q = From x In c Where True Select x End Sub End Module
Foo
Select
, , Where
. Select
, , Select
, Integer
. C# , .Where
( Select
). , , .Let
, C# — . , VB, C# 2012 , : using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace CSharpExamples { struct Point { public int X { get { return 0; } } public int Y { get { return 0; } } } class Foo { public IEnumerable<Point> Select<T>(Func<string, T> selector) { return new Point[0]; } } static class Program { static void Main(string[] args) { var c = new Foo(); var q = from X in c let Y = "" select Y.CompareTo(-1); } } }
string
. let
Y
, string. , Point, X
Y
, , int
X
Y
, «» . Y
select
, int
int
`, … .As
From
cast
; 'As'
From x As Integer In y
VB, , from int x in y
C#..Cast<T>()
. VB , , , , ..Cast
( ). , , , .Cast
.Select
.For Each x As T In collection
, As T
. From
As
For Each
( , As
).Select
, ,From x In y Where x > 10
. , Select
.From x In y Select x Where x > 10
.From x In y Select x
, From x In y Select x = x
, x
— x
, x
— Select
. Select
.From x In y Select z = x.ToString()
, x
.From x In y Select x.FirstName
, From x In y Select FirstName = x.FirstName
.From x In y Select x.FirstName, x.LastName
— From x In y Select New With {x.FirstName, y.LastName}
, , . IEnumerable(Of $AnonymousType$)
, .Select
, SQL , Select
, . LINQ VB Select , SQL, From .Select
, SQL, - - . VB comma separated ( ) -.Select
, , , , , , , — . Module Program Sub Main() Dim numbers = {1, 2, 3} ' BC36606: Range variable name cannot match the name of a member of the 'Object' class. Dim q = From n In numbers Select n.ToString() End Sub End Module
BC36606: Range variable name cannot match the name of a member of the 'Object' class
BC30978: Range variable '…' hides a variable in an enclosing block or a range variable previously defined in the query expression
— , Object
, , , , . ( n.ToString()
), . , .Minute advertising. 15-16 - .NET- DotNext 2019 Piter . , . , . .
Source: https://habr.com/ru/post/445580/
All Articles