C#はまだ強い! 長い間話されていた革命はキャンセルされました! ほら、仲間! かどうか? TIOBE評価は検索エンジンクエリに基づいており、SO評価は質問された質問のタグに基づいています。 おそらく、VB.NETの開発者は、専門性のない多くの人々を含めて、単にStackOverflowの存在を知らないのでしょうか? または、Google、またはBingを介してそこにたどり着いたのに、質問の仕方が分からないのですか または、十分なMiscrosoftのドキュメントがあり、いくつかの質問はすべて回答済みです。
いずれにしても、VB.NETのシェアは目立って安定していますが、ボリュームに関しては第一位ではありません。 そして、もちろん、そのような結果はデザイナーと言語開発者の強力なチームなしでは不可能でした。 以下は、このチームのメンバーAnthony Greenによる記事の翻訳の2番目の部分です。
内容
非表示のテキスト
コンバージョン数
- 34.ブール変換
- 35. Option StrictがOnに設定されている場合でも、Enumタイプ間およびEnumタイプとそのベースタイプ間の変換は完全に無制限です。
- 36.整数演算のオーバーフローチェック/負のアンダーフローは、コンパイル環境(プロジェクト設定)によって完全に制御されますが、VBとC#は異なるデフォルト値を使用します。 VBでは、オーバーフローチェックはデフォルトで有効になっています
- 37.浮動小数点数を整数型に変換するには、切り捨てるのではなく、バンクの丸め(ベーカーの丸め)を使用します
- 38. NotInheritableクラスを、コンパイル時に実装しないインターフェースとの間で変換することは間違いではありません。
- 39. nullを意味のある型にアンパック(アンボックス)しようとすると、NullReferenceExceptionではなくデフォルトの型の値が発生します。
- 40.ボックス化解除はプリミティブ型の変換をサポートします
- 41.文字列と文字の間には変換があります
- 42.文字列と文字配列の間には変換があります
- 43および44。文字列から数値型および日付型への変換は、リテラル構文をサポートします(通常)
- 45. Char型と整数型の間の変換はありません
表現
- 46.何もない<> null
- 47.括弧は解析の優先度に影響するだけではありません。 変数を値に再分類します
- 48.私は常に構造としても意味として分類されます
- 49.拡張メソッドは単純な名前で使用できます。
- 50.静的インポートはメソッドグループをマージしません
- 51および52。部分名の修飾とスマート名の解決
- 53.コレクション初期化子の追加メソッドは、拡張メソッドにすることができます。
- 54.サイズではなく上限を使用して配列を作成する
- 55. VB配列リテラルcf. magicは、C#で暗黙的に型指定された配列作成式とは異なります
- 56.匿名型のフィールドは可変であり、デフォルトで可変です
- 57. CTypeとDirectCastのどちらも、C#の型キャストではありません。
- 58.一部の「同等の」演算子の優先順位は必ずしも一致しません。
- 59.文字列の連結は異なります。 +と&は、文字列連結のコンテキストが異なります。 + VBで<> + Cで#
- 60.除算は適切に機能します:3/2 = 1.5
- 61. ^まったくMath.Powではない
- 62. = / <>演算子はリンクの等値/不等値になることはありません
- 63.文字列の= / <>演算子は異なります(およびこのコンテキストの他の関係演算子)
- 64. Nullable有効型は3値のロジックを使用します(関係演算子でNULLを伝播します)
- 65.オーバーロードされた演算子は、常に1に対応するとは限りません。
- 66.関数()a = bは()=> a = bとは異なります
- 67.非同期関数lambdaは、非同期void lambdaとして扱われることはありません。
- 68. VBではリクエストは本物(より本物)です
- 69および70。From要求のAs演算子は、常にcastを呼び出すとは限りません。 ボーナスとして、「As」演算子は暗黙的なユーザー変換を呼び出すことができます
- 71〜75。 Selectステートメントはまったく必要ありません。リクエストの途中に表示される場合があり、複数回表示される場合があり、暗黙的または明示的な名前で複数の範囲変数を宣言する場合があります
- 76.結論が必要です...
コンバージョン数
34.ブール変換
Boolean True
を符号付き数値型に変換すると
-1
生成され、符号なし型に変換するとこの型の最大値が得られますが、C#ではこのような変換はありません。 ただし、
Convert.ToInt32
メソッドは、たとえば
True
を
1
に変換するため、
IL
最も頻繁に表現されます。 逆方向では、
0
以外の
0
は
True
変換され
True
。
なんで? VBが
-1
から
1
を使用することを好む理由は、すべての言語でビット単位の0(すべてのビットが0に設定される)の否定が
-1
(すべてのビットが
1
設定される)であるため、この値を使用すると論理的およびビット単位が組み合わされるためです
And
、
Or
Xor
などの操作。
「True」および「False」行との間の変換もサポートされています(もちろん、大文字と小文字は区別されません)。
35. Option StrictがOnに設定されている場合でも、Enumタイプ間およびEnumタイプとそのベースタイプ間の変換は完全に無制限です。
哲学的な観点から、言語は基本的な整数型の名前付き定数のセットとしてではなく、
Enum
型を参照します。 これが最も明白な場所は平等です。 整数を列挙値と比較することは常に許可されますが、C#ではこれはエラーになります。
ストーリータイム: Roslyn APIは多くの内部改訂を経ています。 しかし、それらのそれぞれで、各言語に
SyntaxKind
列挙が割り当てられ、ノードがどの構文を表すかが
IfStatement
ます(例えば、
IfStatement
、
TryCastExpression
)。 開発者は言語から抽象化しようとするAPIを使用し、
SyntaxKind
値の1つを
Integer
としてのみ
SyntaxKind
、生の
Integer
と
SyntaxKind
比較するときにエラーを受け取らず、この開発者はすぐに私のオフィスに来て、不満を言いました: 実装の詳細については、キャストを強制する必要がありました!」
数年後、APIの次の改訂時に、言語固有の型を指すプロパティ(
Property Kind As SyntaxKind
)を完全に削除し、すべてのAPIが
Integer
を返し始めました。 すべてのC#コードが破損し、すべてのVBコードは何も起こらなかったかのように機能し続けました。
少し後に、このプロパティの名前を
RawKind
に変更し、言語固有の拡張メソッド
Kind()
を追加することにしました。 メソッドを呼び出すために括弧が必要だったため、すべてのC#コードが壊れましたが、VBでは必要なかったため、すべてのVBコードは、何も起こらなかったかのように再び機能し続けました。
36.整数演算のオーバーフロー/負のオーバーフローのチェックは、コンパイル環境(プロジェクト設定)によって完全に制御されますが、VBとC#は異なるデフォルト値を使用します。 VBでは、オーバーフローチェックはデフォルトで有効になっています
整数型には範囲があるため、たとえば、
Byte
は0〜255の値を表すことができます。
Byte
1を
Byte
255に追加するとどうなりますか。 オーバーフロー/アンダーフローが無効な場合、値は0にスクロールします。型が符号付きの場合、負の最小数(たとえば、
SByte
-128)にスクロールします。 これはおそらく、プログラムのエラーを示しています。 オーバーフロー/アンダーフローのチェックが有効になっている場合、例外がスローされます。 意味を理解するために、この無害な
For
ループを見てください。
Module Program Sub Main() For i As Byte = 0 To 255 Console.WriteLine(i) Next End Sub End Module
githubソースコード
デフォルトでは、このループはVBで例外をスローします(ループの最後の反復が
Byte
境界を超えるためです。ただし、オーバーフローチェックをオフにすると、255 iが再び0になるためループします。
アンダーフローは、そのタイプの最小値を下回ると最大値になるという反対の状況です。
より一般的なオーバーフローの状況は、単純に2つの数字を加算することです。 両方とも
Byte
として130と150の番号を
Byte
ます。 それらを合計すると、答えは280になり、Byteに収まりません。 しかし、プロセッサはこれを認識しません。 代わりに、彼は答えが24だと報告しています。
ところで、これは変換とは関係ありません。 2バイトを追加すると1バイトになります。 これは、バイナリ数学の機能です。 ただし、LongからIntegerへの変換を試みる場合など、変換を実行することでオーバーフローが発生することもあります。 オーバーフローをチェックせずに、プログラムはこの変数に収まる範囲で余分なビットやスタッフをカットします。
違いは何ですか? パフォーマンス。 CLRのオーバーフローをチェックするには、他のすべてのセキュリティチェックと同様に、非チェックオプションに比べて計算時間が少し長くなります。 VBは、開発者の生産性が計算パフォーマンスよりも重要であるという哲学に基づいているため、デフォルトではセキュリティチェックが有効になっています。 今日のC#開発チームはプロジェクトのデフォルト設定について異なる決定を下すかもしれませんが、最初のC#開発者はC / C ++開発者から来たことを考えると、このグループの人々はおそらくコードがこれ以上何もしないことを要求し、プロセッササイクルを犠牲にする可能性があります; これは難しい哲学的な違いです。
ニュアンス:オーバーフロー/アンダーフローチェックがオフになっている場合でも、
Single
または
Double
の
PositiveInfinity
、
NegativeInfinity
、
NaN
から
Decimal
への変換は例外
Decimal
スローします。これらの値は原則としてDecimalで表現できないためです。
37.浮動小数点数を整数型に変換するには、切り捨てるのではなく、バンカーの丸めを使用します
VBで1.7を整数に変換すると、結果は2になります。C#では、結果は1になります。アメリカ以外の数学的規則については何も言えませんが、実数から整数に切り替えると、本能的に丸められます。 そして、プログラマーのサークルの外で私が知っている人は誰も、1.7に最も近い整数が1であるとは考えていません。
実際には、いくつかの丸め方法があり、VB(およびMath.Roundメソッド)で使用される丸めの種類は、デフォルトで銀行の丸めまたは統計家の丸めと呼ばれます。 その本質は、2つの整数の中間の数値に対して、VBは最も近い偶数に丸めることです。 1.5は2に丸められ、4.5は4に丸められます。学校で教えられたように実際に機能しないのは、0.5から切り上げるように教えられました(技術的には、ゼロから横に丸める)。 しかし、その名前が示すように、銀行の丸めには、多数の計算を使用して、半分に丸めるときに分割し、常にお金を渡したり、常にお金を維持したりしないという利点があります。 つまり、大規模なセットでは、これによりデータの歪みが最終的な統計偏差に制限されます。
違いはどこから来ますか? 丸めはより直感的で実用的であり、切り捨てが速くなります。 LOBアプリケーション、特にVBAで実行されるExcelマクロなどのアプリケーションでVBを使用することを検討する場合、単に小数点以下の桁を削除すると問題が発生する可能性があります。
変換の方法は常に物議を醸す問題であり、明示的に示す必要があることは明らかだと思いますが、1つを選択する必要がある場合は...
38. NotInheritableクラスを、コンパイル時に実装しないインターフェースとの間で変換することは間違いではありません。
一般的に、インターフェイス実装のNonInheritableクラスをチェックしている場合、このタイプとそのすべての基本タイプのすべてのインターフェイスを知っているため、コンパイル時にそのような変換が可能かどうかを理解できます。 型が継承される場合、そのような変換が不可能であることを確信することはできません。なぜなら、それによって参照されるランタイムオブジェクトの型は、実際にこのインターフェイスを実装するより派生した型を持っているからです。 ただし、COM相互運用機能に起因する例外があります。コンパイル時に、型がインターフェイスに関係していることが表示されない場合がありますが、実行時には表示されます。 このため、このような場合、VBコンパイラは警告を生成します。
なんで? VBとCOMは、古い近所の子供の頃一緒に育ちました。 そのため、言語設計には、VBが.NET 1.0のリリース時にCOMにのみ存在していたものに多大な注意を払ういくつかのソリューションがあります。
39. nullを意味のある型にアンパック(アンボックス)しようとすると、NullReferenceExceptionではなくデフォルトの型の値が発生します。
技術的にはこれは参照型にも当てはまると思いますが、そうです:
CInt(CObj(Nothing)) = 0
なんで?
CInt(Nothing) = 0
であり、変数を入力したかどうかに関係なく、言語はある程度一貫している傾向があります。 これは、組み込みの意味のある型だけでなく、あらゆる構造に適用されます。 詳細については、#25の根拠を参照してください。
40.ボックス化解除はプリミティブ型の変換をサポートします
VBとC#の両方で、
Short
を
Integer
に変換できますが、パックされた
Short
を
Integer
に変換しようとするとどうなりますか? VBでは、
Short
は最初にアンパックされ、次に
Integer
変換されます。 C#では、
int
に変換する前にshortを手動でアンパックしない限り、
InvalidCastException
がスローされます。
これは、すべての内部変換、つまりパック数値型、文字列と数値型の間の変換、文字列と日付(はい、10進数、および日付はプリミティブ型です)に適用されます。
なんで? 繰り返しますが、一貫した動作を確保するために、プログラムが完全に型付けされているか、Objectとして型付けされているか、あるオプションから別のオプションにリファクタリングされているかどうか。 上記の#39を参照してください。
41. String
とChar
間には変換があります
-
String
、最初の文字を表すChar
に変換されます。 -
Char
String
合理的な方法でのみString
変換されます。
私以外の誰もVBの文字リテラルの構文を覚えていないので(覚えてはいけません)。
42. String
とChar
配列の間には変換があります
-
String
、そのすべての文字で構成されるChar
配列に変換されます。 -
Char
配列は、そのすべての要素で構成されるString
変換されます。
明確にするために、これらの変換は新しいオブジェクトを作成しますが、内部の
String
構造にはアクセスできません。
面白い話: .NET 3.5と4.0の間の
String.Join
な変更を見つけた(または報告して、調査していた)のは、.NETチームが2番目の
String.Join
オーバーロード
String.Join
に
ParamArray
修飾子を追加したためです。 。 正確な仮定は時間の経過とともに失われます(おそらく良い方向に)が、信じているように、
ParamArray
修飾子を使用すると、
Char
配列を文字列に変換し、別の要素としてパラメーター配列に渡すことができるようになりました。 楽しいテーマ。
43および44。文字列から数値型および日付型への変換は、リテラル構文をサポートします(通常)
-
CInt("&HFF") = 255
-
CInt("1e6") = 1_000_000
-
CDate("#12/31/1999#") = #12/31/1999#
これはベースプレフィックスで機能し、16進数(または8進数)入力を
CInt("&H" & input)
に変換する非常に便利な方法を使用できるようにします。 残念ながら、VBランタイムはバイナリプレフィックス&Bまたは
1_000
桁のグループ
1_000
をサポートするように更新されていないため、この執筆時点でこの対称性は低下していますが、これは次のバージョンで修正されることを願っています。 科学表記法は機能しますが、タイプサフィックスがなく、日付変換も標準の日付形式をサポートするため、ISO-8601で使用されるJSON形式も機能し
CDate("2012-03-19T07: 22Z") = #3/19/2012 02:22:00 AM#
。
なんで? 便利さ以外の理由は知りません。 しかし、#FF、U + FF、0xFFなど、今日のネットワークでほぼどこにでもある他の一般的な形式のサポートを提供したいと思います。 これにより、ある種のアプリケーションでの生活が大いに楽になると思います...
45. Char
型と整数型の間の変換はありChar
何?!?!?
これらすべての追加の変換について読んだ後、あなたは驚きましたか? VBは
Char
と
Integer
間の変換を禁止します:
-
CInt("A"c)
はコンパイルされません。 -
CChar(1)
はコンパイルされません。
なんで? 何が起こるかは明確ではありません。 通常、このような状況でVBは実用的かつ/または直感的なアプローチを使用しますが、
CInt("1")
を表現するために、読者の半分は数字1(文字値1)を期待し、半分は数字49(ASCII / UTFコード文字1)。 半分のケースで誤った選択をする代わりに、VBには、文字をASCII / Unicodeコードに、およびその逆に
ChrW
それぞれ
AscW
と
ChrW
変換するための特別な機能が
ChrW
ます。
表現
46.何もない<> null
VBのリテラル
Nothing
はnullを意味しません。 これは「使用される型のデフォルト値」を意味し、参照型の場合、デフォルト値はnullになります。 違いは、次の状況で使用する場合にのみ重要です。
- 何も重要なタイプを取りません、そして...
- 彼がこれをしていることは、文脈から明らかではありません。
これが何を意味するかを説明するいくつかの例を見てみましょう。
1つ目は、少し奇妙かもしれませんが、このプログラムが「True」を出力するという理解にほとんどの人が感動することはないと思います。
Module Program Sub Main() Dim i As Integer = 0 If i = Nothing Then Console.WriteLine("True") End If End Sub End Module
githubソースコード
その理由は非常に簡単です。
Integer (0)
をそのタイプのデフォルト値
Integer (0)
と比較しています。 この問題は、Null許容の意味のある型を追加するとVB2005 / 2008で発生します。 この例を見てください:
Module Program Sub Main() Dim i = If(False, 1, Nothing) End Sub End Module
githubソースコード
タイプ
i
が
Integer?
ことをどのように提案でき
Integer?
(
Nullable(Of Integer)
)。 しかし、これはそうではありません。
Nothing
コンテキストから型を取得せず、このコンテキストの唯一の型は第2オペランドから取得され、これは単純な
non-nullable Integer
(技術的には、
Nothing
には型があり
Nothing
ん)。 この問題を見るもう1つの方法は、次の例です。
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
githubソースコード
繰り返しになりますが、ここでは直感的に、
Nothing
は「nullable」ヒントを追加し、言語は
nullable
を受け入れるオーバーロードを選択しますが、そうではありません(「
non-nullable
」は「最も具体的」なので選択します)。 少なくとも、C#のnullのように、式
Nothing
は
Integer
はまったく適用されず、例外メソッドによってnullableオーバーロードが選択されると仮定できますが、これは
Nothing = null (Is null?)
という誤った考えに基づいてい
Nothing = null (Is null?)
。
Nuance: VBの
Nothing
に一致する新しい
default
式がC#7.1に追加されました。
null
代わりに
default
を使用してC#で上記の3つの例をすべて書き換えると、まったく同じ動作になります。
これについて何ができますか? いくつかの提案がありますが、まだ勝者はいません。
-
Nothing
有効な型に変換され、null
が有効な有効な型ではnull
でないことを警告するたびに警告を表示します。 - 実行時の値が次のいずれかになるたびに、
Nothing
をChrW(0)
、ChrW(0)
、False
、#1/1/0001 12:00:00 AM#
ChrW(0)
#1/1/0001 12:00:00 AM#
ChrW(0)
#1/1/0001 12:00:00 AM#
またはNew T
(任意の構造のデフォルト値ChrW(0)
に美しく展開します上記のリスト。 - 「Null、no、really!」を意味する新しい構文を追加します
Null
Nothing?
-
If(False, 0?, Nothing)
、値をnullableにラップして型を推測するのに役立つサフィックス(?)の形式で新しい構文を追加します -
If (False, CInt? (0), Nothing)
ように、型推論にヒントを提供しやすくするために、組み込み型にNULL入力可能な変換演算子を追加します
コメントやTwitterであなたの意見を聞きたいです。
要約すると:
- 以前-VB6とVBAには「なし」、「ヌル」、「空」、および「欠落」があり、異なることを意味します。
- 2002-VB.NETには
Nothing
(特定のコンテキストのデフォルト値)のみがあり、C#にはnull
のみがありnull
。 - 2005-C#は
default(T)
(タイプT
デフォルト値default(T)
追加しdefault(T)
。これは、新しく追加されたジェネリックにより、値を初期化する必要がある状況が作成されるためです。 このスクリプトはすでにNothing
によって閉じられているため、VBは何もしNothing
。 - 2017-
T
指定T
冗長または不可能な多くのシナリオがあるため、C#はdefault
(コンテキストのdefault
値)を追加しdefault
VBは、
Null
式(または同等のもの)の追加に抵抗し続けています。理由は次のとおりです。
- 構文は破壊的な変更になります。
- 構文が変更を壊すことはありませんが、コンテキストによって異なることを意味します。
- 構文はあまりにも目立たなくなります(たとえば、
Nothing?
)。Nothing
andNothing?
について大声で話す必要があると想像してくださいNothing?
人に何かを説明するために。 - 構文がtooすぎます(例:
Nothing?
)。 - null式スクリプトは
Nothing
によって既に閉じられており、この関数はほとんどの場合完全に冗長です。 - どこでも、すべてのドキュメントとすべての指示を更新して、新しい構文の使用を推奨する必要があります。これは、ほとんどのシナリオで基本的に廃止され
Nothing
宣言します。 - 実行時、遅延バインディング、変換などに関して、
Nothing
もNull
が同じように動作することはありNothing
。 - 刺すような銃のようなものです。
そのようなもの。
オフトピック(関連する)
上記の2番目の例と非常によく似ていますが、型の推論はありません。
Module Program Sub Main() Dim i As Integer? = If(False, 1, Nothing) Console.WriteLine(i) End Sub End Module
githubソースコード
このプログラムは0を表示します。同じ理由で2番目の例とまったく同じように動作しますが、関連していても別の問題を示しています。 直感的に、
Dim i as Integer? = If(False, 1, Nothing)
Dim i as Integer? = If(False, 1, Nothing)
が
Dim i As Integer? : If False Then i = 1 Else i = Nothing
と同じように動作する
Dim i as Integer? = If(False, 1, Nothing)
Dim i As Integer? : If False Then i = 1 Else i = Nothing
Dim i As Integer? : If False Then i = 1 Else i = Nothing
。 この場合、条件式
(If)
は最終型の情報をオペランドに「パススルー」しないため、これはそうではありません。 これにより、最終的な(コンテキスト)タイピング(
Nothing
、
AddressOf
、リテラルの配列、ラムダ式、および補間された文字列)と呼ばれるものに依存するVBのすべての式が、一般的な非コンパイルから静かに誤った値の作成に至るまでの問題に分解されることが
AddressOf
ます大声で例外をスローします。 コンパイルされていないオプションの例を次に示します。
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
githubソースコード
このプログラムはコンパイルされません。 代わりに、両方の
AddressOf
式が
Func(Of Integer, Integer, Integer)
デリゲート
Func(Of Integer, Integer, Integer)
を受信することを
AddressOf
意図している場合、式のタイプを判別できないというエラーを
If
式で報告します。
,
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 .
なんで? 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.io —
BoundParenthesized
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()
.
なんで? ,
'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# , , .
なんで? , , VB , C# ( ). , ( , ), … , .
, VB , VB , , , , , ( #6 ). VB . , VB 2002 .
51 52. (Partial-name qualification & Smart-name resolution)
:
- , — ( ).
System
System.Windows.Forms
— , ,System
System.Windows
System.Windows
System.Windows.Forms
. - , , , .
System
Windows
,Windows
Form
.
, , . . 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 ( ) , — . :
-
CType({1, 2, 3}, Short())
CType(New Integer() {1, 2, 3}, Short ())
,Integer
Short
. -
CType({1, 2, 3}, Short())
New Short() {1, 2, 3}
. .
, , VB , C#. , :
-
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
.
なんで? , VB. , . 2008 VB C# «» {}, - ( , , ). , , , + , . .
56.
, LINQ. , .
, , .
57. CType, DirectCast C#
/ VB C#.
VB
CType
:
- ;
- ( );
- , ,
Long
Integer
(. «»); - (unboxes) ;
- ;
- (
CTypeDynamic
).
VB
DirectCast
:
- ;
- ;
- (
Integer Byte
); - ;
- ( );
- .
C# —
(Type)expression
:
- ;
- ;
- ;
- ;
- ;
- .
CType
C# , . , . VB C# , IL . , C#, , . .
,
CType
, (, ).
CType
,
DirectCast
, . , , IL :
Object
(
ValueType
) CLR «unbox» VB-, , (,
Short
Integer
). , , C#. . , .
なんで? . , , , , .
58. «»
, ,
5 Mod 2 * 3
5 VB, «» C#
5 % 2 * 3
3.
, , . , (, (\) VB), , , . !
59. ; + & ; + VB <> + C#
, + () & () VB + C#.
String
:
VB
- “1” + 1 = 2.0
- “1” & 1 = “11”
C#
- «1» + 1 == «11»
, + &
VB
- “obj: “ + AppDomain.CurrentDomain ' Error: + not defined for String and AppDomain.
- ”obj: “ & AppDomain.CurrentDomain ' Error: & not defined for String and AppDomain.
- ”obj: “ + CObj(AppDomain.CurrentDomain) ' Exception, no + operator found.
- ”obj: “ & CObj(AppDomain.CurrentDomain) ' Exception, no & operator found.
C#
- «obj: » + AppDomain.CurrentDomain == «obj: » + AppDomain.CurrentDomain.ToString()
- «obj: » + (object)AppDomain.CurrentDomain == «obj: » + AppDomain.CurrentDomain.ToString()
- «obj: » + (dynamic)AppDomain.CurrentDomain == «obj: » + AppDomain.CurrentDomain.ToString()
:
VB
- 1 + 1 = 2
- 1 & 1 = “11”
C#
- 1 + 1 == 2
String Enum:
VB
- “Today: ” + DayOfWeek.Monday ' Exception: String «Today: » cannot be converted to Double.
- “Today: ” & DayOfWeek.Monday = “Today: 1”
- “Today: ” & DayOfWeek.Monday.ToString() = “Today: Monday”
C#
- «Today: » + DayOfWeek.Monday == «Today: Monday»
: , + VB, - . + , , - . なんで? なぜなら:
- “10” — “1” = 9.0,
- “5” * “5” = 25.0,
- “1” << “3” = 8,
- “1” + 1 = 2.0,
- “1” + “1” = “11”
. — .
: +, . , &, , ( , ). , , .
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. それは:
- /: “A” = “a”/“A” <> “a”
- : “A” > “a”
-
Select Case: Select Case “A” : Case “a”
:
-
Equals: “A”.Equals(“a”)
-
Contains: ”A”.Contains(“a”)
-
Distinct: From s In {“A”, “a”} Distinct
, , : 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)
.
, , , , , . , , .
なんで?
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,
Is/IsNot
,Boolean?
- C# (==, !=, >, <, >=, <=)
bool
bool?
VB ( nullable ) null null .
Boolean
=
Boolean?
,
True
,
False
null
. . C#
non-nullable bool
, .
, . null. VB NULL = NULL — NULL , 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, :
- 1 AND NULL NULL
- 1 OR NULL NULL
Boolean?
, VB .
- FALSE AND NULL FALSE
- TRUE OR NULL TRUE
- TRUE AND NULL NULL
- FALSE OR NULL NULL
,
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.
そのようなもの。
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#, . , ( , ), - .
なんで? , , , . , , 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
.
なんで? 手がかりはありません。 VB . ,
For Each x As T In collection
,
As T
.
From
As
For Each
( ,
As
).
71-75. 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$)
, .
なんで? ( Amanda Silver ). !
- ,
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
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 ( — .. ).
広告の分。 15-16 - .NET- DotNext 2019 Piter . , . , . .