📜 ⬆️ ⬇️

An exhaustive list of differences between VB.NET and C #. Part 2

In the first part of the article, the topic of VB.NET superiority over C # by TIOBE rating found a lively response in the comments. Therefore, on the advice of AngReload, we will look at StackOverflow trends .

C # is still strong! The revolution that was talked about for so long last time is canceled! Cheers, comrades! Or not? The TIOBE rating is based on search queries, and the SO rating is based on the questions asked. Perhaps the developers of VB.NET, which include many people in non-IT specialties, simply do not know about the existence of StackOverflow? Or having got there through Google, and even Bing, do not understand how to ask a question? Or maybe Miscrosoft documentation is enough for them, and all the few questions have already been answered.

Anyway, the share of VB.NET is noticeable and stable, even if not in the first place in terms of volume. And, of course, such a result would have been impossible without a strong team of designers and language developers. Below is the second part of the translation of the article of the team member, Anthony Green .

Content


Hidden text

Transformations



Expressions



Transformations


34. Boolean transformations


A 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 .

Why? The reason why VB prefers to use from -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 .
Conversions to and from the “True” and “False” strings are also supported (of course, case insensitive).
')

35. Conversions between Enum types, as well as between Enum types and their base types are completely unlimited, even if Option Strict is set to On


From a philosophical point of view, the language refers to 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.

Time stories: The Roslyn API has gone through many internal revisions. But in each of them, for each language, the 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! " .

Years later, during the next API revision, we completely removed the properties ( 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.

A little later, we decided to rename this property in 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.

36. Checking overflow (overflow) / negative overflow (underflow) for integer arithmetic is completely controlled by the compilation environment (project settings), but VB and C # use different default values; overflow is enabled by default in VB


Integral types have a range, so, for example, 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 

source code on github

By default, this cycle will throw an exception in VB (since the last iteration of the cycle goes beyond the Byte boundary. But with the overflow check turned off, it loops because after 255 i becomes 0 again.
Underflow is the opposite situation, when subtraction is lower than the minimum for the type of value leads to the maximum value.

A more common situation for overflow is simply the addition of two numbers. Take the numbers 130 and 150, both as 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.

By the way, this has nothing to do with transformations. Adding two bytes gives bytes; it's just the way binary mathematics works. Although you can also get an overflow by doing the conversion, for example, when you try to convert Long to Integer. Without an overflow check, the program simply cuts off the extra bits and stuffs as much as it fits into this variable.

What is the difference? Performance. An overflow CLR check requires a little more computational time than the unchecked option, like all other security checks. VB is based on the philosophy that developer productivity is more important than computing performance, so by default you have security checks enabled. The C # development team today can make a different decision on the default settings of the project, but when you consider that the first C # developers came from C / C ++ developers, this group of people would probably require the code to do nothing extra that could cost processor cycles ; This is not a simple philosophical difference .

Nuance: even if overflow / underflow checking is disabled, converting 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.

37. Converting floating-point numbers to integer types uses banking rounding (bankers rounding) rather than truncating


If you convert the number 1.7 into an integer in VB, the result will be 2. In C #, the result will be 1. I cannot say anything about the mathematical rules outside of America, but I go round from real number to integer instinctively. And none of those whom I know outside the circle of programmers consider that the closest integer to 1.7 is 1.

In fact, there are several rounding methods, and the type of rounding used in VB (and in the Math.Round method) is by default called bank rounding or statistics rounding. Its essence is that for a number in the middle between two integers, VB rounds to the nearest even number. So 1.5 is rounded up to 2, and 4.5 is rounded up to 4. What actually works is not the way we were taught in school - I was taught to round up from 0.5 (technically, round off from zero). But, as the name implies, banking rounding has the advantage that with a large number of calculations, you divide by rounding in half, rather than always distributing or always holding money. In other words, on a large set, this limits the distortion of data to the limiting statistical deviation.

Where does the difference come from? Rounding is more intuitive and practical, truncation is faster. If you consider using VB in LOB applications and especially in applications such as Excel macros running on VBA, simply dropping the numbers after the comma can cause ... problems.

I think it is obvious that the method of transformation is always an ambiguous question and should be explicitly stated, but if you need to choose a single ...

38. It is not an error to convert NotInheritable classes to / from interfaces that they do not implement at compile time.


Generally speaking, if you check a NonInheritable class for an interface implementation, you can understand at compile time whether such a transformation is possible, because you know all the interfaces of this type and all its basic types. If the type is inheritable, you cannot be sure that such a conversion is impossible, because the type of the runtime object referenced may actually have a more derived type that implements this interface. However, there is an exception due to COM interop, when at compile time it may not be visible that the type has anything to do with the interface, but at runtime it will be so. For this reason, the VB compiler issues a warning in such cases.

Why? VB and COM grew up together at a time when they were children in the old district. So in language design there are several solutions in which VB pays great attention to things that existed only in COM at the time of the release of .NET 1.0.

39. Attempting to unpack (unbox) null to a meaningful type results in a default type value, not NullReferenceException.


I suppose that technically this is also true for reference types, but yes:
 CInt(CObj(Nothing)) = 0 

Why? Because 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.

40. Unboxing supports primitive type conversions.


Both in VB and in C # you can convert 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.
This applies to all internal transformations, that is, packed numeric types, conversions between strings and numeric types, strings and dates (yes, Decimal and Date are primitive types).

Why? Again, to ensure consistent behavior, whether your program is completely strongly typed, typed as Object, or is in the process of refactoring from one variant to another. See # 39 above.

41. There are conversions between String and Char



Because no one except me remembers the syntax of a character literal in VB (and should not).

42. There is a conversion between String and Char array



For definiteness: these transformations create new objects, you do not get access to the internal structure of the String .

Funny story: I once found (or perhaps it was reported, and I researched) breaking change between .NET 3.5 and 4.0, because between these versions, the .NET team added the 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.

43 and 44. Conversions from String to numeric and date types support the syntax of literals (as a rule)



It works with base prefixes and makes it possible to use a very convenient way to convert hexadecimal (or octal) input to a number: 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# .

Why? I do not know any other reason than convenience. But I would really like to offer support for other common formats that are almost ubiquitous today, such as # FF, U + FF, 0xFF. I think it could make life much easier in some types of applications ...

45. NO conversion between Char and integer types


WHAT?!?!?
After reading about all these additional conversions, are you surprised? In VB, conversions between Char and Integer are prohibited:


Why? It is unclear what should happen. Usually VB in such situations uses a pragmatic and / or intuitive approach, but for expressing 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.

Expressions


46. ​​Nothing <> null


The literal 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:

  1. Nothing takes on a significant type, and ...
  2. From the context it is not clear that he does it.

Let's look at a few examples that illustrate what that means.

The first one is perhaps a bit strange, but I don’t think that most people will be blown away by the brain with the understanding that this program will print “True”:

 Module Program Sub Main() Dim i As Integer = 0 If i = Nothing Then Console.WriteLine("True") End If End Sub End Module 

source code on github

The reason is quite simple: you compare 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 

source code on github

It is clear how someone can assume that type 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 

source code on github

Again, here it seems intuitively that 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?) .

Nuance: a new expression has been added to C # 7.1, which corresponds to Nothing in VB. If you rewrite all three examples above in C # using default instead of null , you will get exactly the same behavior .

What can be done about this? There are several offers, but none have won yet:


I would like to hear your thoughts in the comments and / or on Twitter .

So let's summarize:


VB continues to resist the addition of a Null (or equivalent) expression because:


Something like this.

Offtop (but related)

Here is an example, very similar to the second one above, but with no type output:

 Module Program Sub Main() Dim i As Integer? = If(False, 1, Nothing) Console.WriteLine(i) End Sub End Module 

source code on github

This program displays 0. It behaves exactly the same as the second example, for the same reason, but it illustrates a separate, albeit related problem. Intuitively, what is 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 

source code on github

This program will not compile. Instead, it reports an error in an 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 ( ) () — , .

47. ;


«3»:

 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 

GitHub

C# «-3». , VB — , . , M(3) , M(i) , i , . C# ( ) , M .

Why? VB . Quick Basic (Copyright 1985), . , 2002 , .

№1: « » , Visual Basic .NET.
№2: Roslyn ( , ( ) ( )), : . C# , ((a + b) * c a + (b * c)) . , C#, C++, , , , . : « VB?» « C#?» source.roslyn.ioBoundParenthesized VB C#. , , .

48. Me


VB.NET Me . , - , — , Me Structure . Me . C# this , this .

49.


VB, , :

 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 

GitHub

C# ( something.Extension). , C#, , this.Extension() .

Why? , 'Me.' , , , , . VB.NET . , .

50. (Static imports will not merge method groups)


VB « » (Java-, C# VB). , Imports System.Console WriteLine() . 2015 C# . VB Shared- , System.Console System.Diagnostics.Debug , WriteLine , . C# , , .

Why? , , VB , C# ( ). , ( , ), … , .

, VB , VB , , , , , ( #6 ). VB . , VB 2002 .

51 52. (Partial-name qualification & Smart-name resolution)


:


, , . . VB Imports , using C# .

, VB System , System , System . , . , ExtensionAttribute , <Runtime.CompilerServices.Extension> <System.Runtime.CompilerServices.Extension> .

C# . using System System.Threading Threading .

, C# , . , System , System.Threading Threading . , , , , .

, , VB, C# , Imports / using , C# using , , using .

(Quantum Namespaces) ( )

, ! VB , . , System ComponentModel System.Windows.Forms ComponentModel ? ComponentModel . , ComponentModel.PropertyChangedEventArgs , ( , ). System.Windows.Forms (, , , , ), (ambiguity errors).

VB2015 (Smart Name Resolution), 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 .

53. Add


#33 , VB - , . , , — , :

 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 

GitHub

C# , Roslyn C#, . , ( , ), VS2015.

54. ,


, VB Dim buffer(expression) As Byte Dim buffer = New Byte(expression) {} expression + 1 .

Microsoft BASIC, DIM ( dimension — ). , , , : 0 expression. Microsoft BASIC 1 ( , 1984), ( ), 2002 .

, - , , VB , BASIC C , , C, C- . , buffer(10) 0 10, 9!

55. VB - , C#


, . , VB ( ) , — . :


, , VB , C#. , :


:


( ):


, IList(Of T) , IReadOnlyList(Of T) , ICollection(Of T) , IReadOnlyCollection(Of T) IEnumerable(Of T) , , , ParamArray IEnumerable .

Why? , VB. , . 2008 VB C# «» {}, - ( , , ). , , , + , . .

56.


, LINQ. , .

, , .

57. CType, DirectCast C#


/ VB C#.
VB CType :


VB DirectCast :


C# — (Type)expression :


CType C# , . , . VB C# , IL . , C#, , . .

, CType , (, ). CType , DirectCast , . , , IL : Object ( ValueType ) CLR «unbox» VB-, , (, Short Integer ). , , C#. . , .

Why? . , , , , .

58. «»


, , 5 Mod 2 * 3 5 VB, «» C# 5 % 2 * 3 3.

, , . , (, (\) VB), , , . !

59. ; + & ; + VB <> + C#


, + () & () VB + C#.
String :
VB


C#


, + &
VB


C#


:
VB


C#


String Enum:
VB


C#


: , + VB, - . + , , - . Why? Because:


. — .

: +, . , &, , ( , ). , , .

60. : 3 / 2 = 1,5


— : « ?» . «». : « . ?»
VB C#.

C, , , « 5 9?» , \. , , , , 0 ( , - INumeric ).

61. ^ Math.Pow


Math.Pow . , . , ( custom ) ( , System.Numerics.BigInteger ).

: F# **, VB F# : op_Exponent op_Exponentiation . F# Pow . . , .

62. =/<> /


C# '==' () , , ( ). VB . VB ( Is/IsNot ) .

: - Roslyn , . . . VB , = , C# , , , .

63. =/<> ( )


VB .

-, ( ) - ( ), , Option Compare Binary Option Compare Text . Option Compare Binary , , VS.

( ), , API. :


:


, , : VB . , Option Compare , «Empty».

 Module Program Sub Main() Dim s As String = Nothing If s = "" Then Console.WriteLine("Empty") End If End Sub End Module 

GitHub

s = "" VB — String.IsNullOrEmpty(s) .
, , , , , . , , .

Why? Option Compare Text , , . , , .
, , , , .

, , . , . , , (collation) SQL Server, . , VB VB6, VBA Office, Excel Access, VBScript Windows, -, -… . , , .NET API , Option Compare Text, . , .NET API, .

null, , . VB6 . String "". , VB String . VB, Left Mid , String . null . Len(CStr(Nothing)) = 0 Left(CStr(Nothing) , 5) = "" , CStr(Nothing).Length CStr(Nothing).Trim() .

, ? . ( ).

:
, , , . ! VB , , "String A" = "String B" , Microsoft.VisualBasic.CompilerServices.Operators.CompareString , - , , . LINQ- . , VB ( ). , , - , . LINQ-to-SQL, LINQ-to-Entities , Microsoft. , VB , !

, C#, VB, LINQ . : 1) , VB , , 2) , VB , , LINQ-. , VB ().

: , « API». Option Compare VB, InStr.Replace Microsoft.VisualBasic.Strings . , ?

, , , ? , , , : , , .

64. Nullable ( null )


VB C# - nullable. , (null-propagation).

SQL, , , null. , (, +), null, null. "?." : obj?.Property obj null, null, .

nullable , VB, C# . - : .

VB, nullable , null, null . 1 + null null null + null null. , (, = <>) C#:


VB ( nullable ) null null . Boolean = Boolean? , True , False null . . C# non-nullable bool , .

, . null. VB NULL = NULLNULL , TRUE.
, :

. Null , , , C# .

. C# VB, « null?» C# (if (value == null)) . VB , VB (=/<>) (Is/IsNot) , VB Is Nothing non-nullable Boolean .

, VB null, null. And/AndAlso Or/OrElse .

Integer? ( ), VB, C# null, :


Boolean? , VB .


, True/False , , null. , AndAlso OrElse .

C# (&&/||) (&/|) nullable boolean (bool?) . , , non-nullable boolean nullable boolean .

?
VB , - :

 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 

GitHub

, , , , «EndDate change» . , , VB null ? , EndDate , , , Nothing .

VB : «, , . » :
 If value <> _EndDate Then _EndDate = value RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(NameOf(EndDate))) End If 

! . , non-nullable . , . , :
 If value Is Nothing AndAlso _EndDate Is Nothing Then Return If value <> _EndDate Then Return 

?
, C# , VB. ( nullable , ), , null.

null — «» « » . .

null « » «» . , , : comparer, , comparer . Roslyn, Optional(Of T) , , , null, , .

, NULL « », VB :


, , SQL- . , NULL SQL , NULL. . , , NULL . , . , , ( ). , , , , , NULL , SQL ( ).

VB. nullable 2008 , VB ?
LINQ to SQL

VB , , , , , , LINQ- . !

. SQL Server, , SET ANSI_NULLS OFF , SQL- C#, WHERE Column = NULL . , , OFF ( ). SQL Server ( ) . : « ? . , - Option ANSI_NULLS Off VB.NET?» . :



, , , , , SQL Server, VB.
Something like this.

65. 1:1


, VB , , , . VB - , .

, , , , . VB , , , , , VB .

9.8.4 .

66. Function() a = b () => a = b


. , () => 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 -) .

67. Async Function async void


C# async -, , , Task void , , Task , .

VB.NET , .. void Async Async Sub , Task Task(Of T)Async Function . , , VB, (relaxing) Task Async void . Async Sub , , .

68. () VB


, VB:

 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 

GitHub

VB, C#. -, Foo Select , , Where . Select , , Select , Integer . C# , .Where ( Select ). , , .

LINQ API. , VB C#, . , C# , « », , , , . - , «» , , -.

, VB , , C# , .

, Roslyn, : « (range variables)?» « ?» . . , VB , 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); } } } 

GitHub

, — ? X, — string . let Y , string. , Point, X Y , , int X Y , «» . Y select , int int `, … .

, « ?» . VS2015 C# , «». , Roslyn C#, . , ( , ), - .

Why? , , , . , , VB C# .

69 70. As From cast ; 'As'


( , …)

From x As Integer In y VB, , from int x in y C#.

-, C# , ( ) . .Cast<T>() . VB , , , , .

-, , .Cast ( ). , , , .Cast .Select .

Why? No idea. VB . , For Each x As T In collection , As T . From As For Each ( , As ).

71-75. Select , ,


For example:


Why? ( Amanda Silver ). !


? , , - , , :

 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 

GitHub

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() ), . , .

76+.


. … … . … 20-25 ( — .. ).

Minute advertising. 15-16 - .NET- DotNext 2019 Piter . , . , . .

Source: https://habr.com/ru/post/445580/


All Articles