C経線の許容可能な参照型—null許容参照型への移行—パート1
15252 ワード
Cの残忍な機能は、C Count 8で導入された場合は、恐怖に遭遇する可能性を最小限に抑える
既存のコードベースに明示的nullabilityを導入することはかなりの努力です.何かを散らかすだけではそれ以上のものがある
一連のブログ記事を通して、私たちはC - Count - Nullabilityについてより多くのことを学び、既存のコードベースを許容できる参照タイプを使用するように移行するときに私のために働いたいくつかのテクニックとアプローチをカバーします.
始めから始めましょう.
あなたは、ヌルが「10億ドル間違い」であると聞いたかもしれません.2009年に、トニーホア(Algol Wプログラミング言語の作者).apologized for his billion-dollar mistake : NULL参照.彼の最初のゴールはどんなリファレンスを使用するのも確実に安全であると保証することでした.しかし、NULLリファレンスをサポートするのは簡単だったので、彼は無数のエラー、脆弱性、およびシステムクラッシュの多くのシステムでそこにつながる.他の言語はこの考えをコピーしました.そして、おそらく、これまでの10億ドルの痛みと損害を引き起こしているnull参照に終わりました.
参照可能な型は常にCの剰余の一部であった.参照型はリファレンスかNULLのいずれかである.次の例を考えます.
チェックを追加できます
などの値型
変換するコンパイラのマジックがあります
C≧8である.nullable reference types (NRT) 導入され、参考にすることができます意図を伝えるのを助ける
はじめに見たように、参照型が常にNULLになっていることを指摘してみましょう.彼らは、最初のバージョンのCount - Count -
なぜ私はこれを指摘していますか?参照型は永遠にnullableされている今、私たちは、デフォルトで非nullableとしてそれらを考えることによって、そのアイデアをひっくり返しており、構文をnull許容できるように注釈を追加します.注釈は、あなたのコードを書いて、コンパイルしている間、助けますが、ランタイム安全ネットを提供しません.その意味を見てみましょう.
null可能な参照型が有効になっている場合、前の例では、コンパイラが
では、Cのどれが参照可能なリファレンスタイプですか?私はnullable注釈を呼び出すように- nrtの可能性があることができますあなたのコードに注釈を付ける.
上記のコードをコンパイルしたり、IDEで見たりするときには、アプリケーションを実行したときにあなたを悩ませるかもしれないいくつかの警告が表示されます. nullリテラルまたは可能なnull値をNull null許容型に変換します. CS 8602 -おそらくNULLリファレンスの参照.
ありがとう, IDE !おかげで、C .これは実行時にすべて爆破するかもしれませんが、少なくともこのコードを修正するのに十分な警告を得ることができます.そして、その修正は、ほぼ自動的に、迅速な修正を行うことができます.
これらの修正を適用した後に、我々は基本的に我々の最初の例で戻っています、しかし、今回は我々が予想するもので注釈をつけられます.また、IDEとコンパイラは私たちを助けてくれます
それがnullabilityとフロー解析に来るいくつかの興味深いものがあります.
例えば、
この例では、
クール、ええ?あなたがするとき、ものはより涼しくなりさえします
包む前に、もう一つの話題があります.NULLを許す演算子(null抑制演算子、またはDammit演算子とも呼ばれます)
null可能な参照型を使用する場合、式は
ここに2つの例があります
有効なユースケースもあります.フロー解析は、許容可能な値が実際に無効であることを検出できないかもしれません.参照がNULLでないということを知っているならば、それらのケースを抑えることができます.次の例では
もう一つのケースは、null許容参照タイプをまだ使用しないコードベースを移行するときです.特定のコードパスに対する警告を一時的に抑制し、コードベースの別の部分で作業しているときには、無効にする必要はありません.
もう一つのケースは、単位テストでありえました.誰かがパスしたらどうなるかチェックしたい
NULLを許す演算子は、フロー解析を効果的に無効にし、コードベースで無効なバグを簡単に隠すことができます.注意して使用し、ヌル抑制演算子の使用を考慮してコードの匂い.
null可能な参照型が有効になっている場合は、コードを参照して静的フロー解析を改善し、コードを参照する前に変数がnullであるかどうかを判断できます.変数のアノテーションを使用して、変数
Nullableな参照型は、それがnullabilityになるとき、あなたにランタイム安全性を与えません、しかし、デザイン時間とコンパイル時間ヘルプは素晴らしいです!
次のポストでは、いくつかのインターナルとNullable注釈コンテキストを見ていきます.
System.NullReferenceException
. null可能性の構文と注釈は、型がnull可能かどうかのヒントを与えます.より良い静的解析は、コードを開発しながら未処理のヌルをキャッチするために利用可能です.何が好きではないですか?既存のコードベースに明示的nullabilityを導入することはかなりの努力です.何かを散らかすだけではそれ以上のものがある
?
and !
あなたのコードを通して.それは、銀弾丸ではありません.あなたはまだnull
.一連のブログ記事を通して、私たちはC - Count - Nullabilityについてより多くのことを学び、既存のコードベースを許容できる参照タイプを使用するように移行するときに私のために働いたいくつかのテクニックとアプローチをカバーします.
始めから始めましょう.
参照型、値型、およびNULL
あなたは、ヌルが「10億ドル間違い」であると聞いたかもしれません.2009年に、トニーホア(Algol Wプログラミング言語の作者).apologized for his billion-dollar mistake : NULL参照.彼の最初のゴールはどんなリファレンスを使用するのも確実に安全であると保証することでした.しかし、NULLリファレンスをサポートするのは簡単だったので、彼は無数のエラー、脆弱性、およびシステムクラッシュの多くのシステムでそこにつながる.他の言語はこの考えをコピーしました.そして、おそらく、これまでの10億ドルの痛みと損害を引き起こしているnull参照に終わりました.
参照可能な型は常にCの剰余の一部であった.参照型はリファレンスかNULLのいずれかである.次の例を考えます.
string s = GetValue();
Console.WriteLine($"Length of '{s}': {s.Length}");
時s
がNULLでない場合、コンソールにメッセージが書き込まれます.しかし、何が起こるかs
はNULLですか?正確にNullReferenceException
にアクセスするとスローされますLength
…の財産null
.チェックを追加できます
null
このプロパティにアクセスする前にstring s = GetValue();
Console.WriteLine(s != null
? $"Length of '{s}': {s.Length}"
: "String is null.");
どのように、あなたはそのチェックを必要とするかどうかわかっていますか?If GetValue()
帰らないnull
, あなたがチェックする必要があるならば、どのように、あなたは知っていますかs
プロパティにアクセスする場合は?などの値型
int
, bool
, decimal
, struct
sDateTime
またはカスタム実装などNullable<T>
これらの値型を“nullable”にし、安全なアクセス方法を持っています.Note: value types can’t really be null - they are values, not references. With
Nullable<T>
, you’re wrapping the value to be able to keep track of this additionalnull
state.
変換するコンパイラのマジックがあります
int?
into Nullable<int>
. null可能な値型にアクセスする場合、null
または値を含み、チェックを行わなければなりません.ヌルブルでDateTime
, 上記の例を次のように書きます.DateTime? s = GetValue();
Console.WriteLine(s.HasValue
? $"The date is: {s.Value:O}"
: "No date was given.");
ここの重要な違いは意図です.我々とstring
前に、あなたはnull
予定です.それは決して起こりません、それは起こるかもしれませんGetValue()
機能(または安全なアプローチを取り、常に追加)null
を参照).値型では、意図はより明確です.エーDateTime
決してありえないnull
, に対してNullable<DateTime>
それをチェックするnull
(or .HasValue
) が必要です.nullableな参照型は何ですか?
C≧8である.nullable reference types (NRT) 導入され、参考にすることができます意図を伝えるのを助ける
null
または、決してnull
.はじめに見たように、参照型が常にNULLになっていることを指摘してみましょう.彼らは、最初のバージョンのCount - Count -
string s = null
すべての参照型は、常に完全に良いです.なぜ私はこれを指摘していますか?参照型は永遠にnullableされている今、私たちは、デフォルトで非nullableとしてそれらを考えることによって、そのアイデアをひっくり返しており、構文をnull許容できるように注釈を追加します.注釈は、あなたのコードを書いて、コンパイルしている間、助けますが、ランタイム安全ネットを提供しません.その意味を見てみましょう.
null可能な参照型が有効になっている場合、前の例では、コンパイラが
s
ないnull
(そうでなければ宣言しますstring? s
), そして、NULLチェックを安全に削除できます.string s = GetValue();
Console.WriteLine($"Length of '{s}': {s.Length}");
string? GetValue() => null;
・・・それともできるのか?驚いたことに、上記のコードをコンパイルして実行することもできますGetValue()
Aを返すstring
それでnull
. あなたは、ちょうどAを見ますNullReferenceException
にアクセスするとスローされますLength
…の財産null
.では、Cのどれが参照可能なリファレンスタイプですか?私はnullable注釈を呼び出すように- nrtの可能性があることができますあなたのコードに注釈を付ける.
上記のコードをコンパイルしたり、IDEで見たりするときには、アプリケーションを実行したときにあなたを悩ませるかもしれないいくつかの警告が表示されます.
ありがとう, IDE !おかげで、C .これは実行時にすべて爆破するかもしれませんが、少なくともこのコードを修正するのに十分な警告を得ることができます.そして、その修正は、ほぼ自動的に、迅速な修正を行うことができます.
これらの修正を適用した後に、我々は基本的に我々の最初の例で戻っています、しかし、今回は我々が予想するもので注釈をつけられます.また、IDEとコンパイラは私たちを助けてくれます
GetValue()
非NULLを返す関数string
, ツールは我々が冗長をしていることを教えてくれますnull
チェックして、削除します.string? s = GetValue();
Console.WriteLine($"Length of '{s}': {s.Length}");
string GetValue() => "";
流れ解析
それがnullabilityとフロー解析に来るいくつかの興味深いものがあります.
例えば、
var
は常にNULLとみなされます.C言語英語チームは常に治療することを決めたvar
nullableとして、フロー解析に依存して、IDEまたはコンパイラが警告しているかどうかを判断します.この例では、
s
は、GetValue()
関数.var s = GetValue();
Console.WriteLine($"Length of '{s}': {s.Length}");
string GetValue() => "";
多くのIDEは、あなたが何を決定するのを助けるインレイタイプヒントをレンダリングしますvar
フロー解析に基づいています.簡単な例です.インレイヒントに注意してくださいvar s
の許容可能性を変更するGetValue()
関数の変更.また、Squigglyで注意してくださいs.Length
, フロー解析がDereferencingかどうか決定するところLength
潜在的にトラブルにあなたを取得する予定です.クール、ええ?あなたがするとき、ものはより涼しくなりさえします
null
チェック.以下に2つのメソッドを示します:void MethodA(string? value) {
Console.WriteLine(value.Length); // CS8602 - Dereference of a possibly null reference.
}
void MethodB(string? value) {
if (value == null) return;
Console.WriteLine(value.Length); // No warning, null check happened before
}
インMethodA()
, 我々はしていないnull
チェックするvalue
パラメータとフロー解析により、null参照を参照することができます.インMethodB()
, フロー解析によるとnull
チェックして、アクセスしている.Length
コードのこの行の可能性がないのでnull
リファレンス.NULLを許す演算子
包む前に、もう一つの話題があります.NULLを許す演算子(null抑制演算子、またはDammit演算子とも呼ばれます)
!
.null可能な参照型を使用する場合、式は
!
IDEとコンパイラの静的フロー解析を指示すると、式のnull状態を「無視」します.ここに2つの例があります
!
は、null解析可能な状態が無視できることをフロー解析に示します.string? a = null;
Console.WriteLine(a!.Length);
string? b = null!;
Console.WriteLine(b.Length);
もちろん、これは理想的ではありませんNullReferenceException
ときにアプリを実行します.有効なユースケースもあります.フロー解析は、許容可能な値が実際に無効であることを検出できないかもしれません.参照がNULLでないということを知っているならば、それらのケースを抑えることができます.次の例では
IsValidUser()
NULLをチェックするので、我々がそうしなければならないNULL警告を抑制することができますConsole.WriteLine
コールvar user = _userManager.GetUserById(id);
if (IsValidUser(user)) {
Console.WriteLine($"Username: {user!.Username}");
}
public static bool IsValidUser(User? user)
=> !string.IsNullOrEmpty(user?.Username);
Note: there are better ways to solve some of these suppressions, using special attributes. I’ll cover these in the next post.
もう一つのケースは、null許容参照タイプをまだ使用しないコードベースを移行するときです.特定のコードパスに対する警告を一時的に抑制し、コードベースの別の部分で作業しているときには、無効にする必要はありません.
もう一つのケースは、単位テストでありえました.誰かがパスしたらどうなるかチェックしたい
null
を参照してください.そのような状況では、あなたはnull!
を参照してください.NULLを許す演算子は、フロー解析を効果的に無効にし、コードベースで無効なバグを簡単に隠すことができます.注意して使用し、ヌル抑制演算子の使用を考慮してコードの匂い.
結論
null可能な参照型が有効になっている場合は、コードを参照して静的フロー解析を改善し、コードを参照する前に変数がnullであるかどうかを判断できます.変数のアノテーションを使用して、変数
?
伝えるnull
参照可能です.Nullableな参照型は、それがnullabilityになるとき、あなたにランタイム安全性を与えません、しかし、デザイン時間とコンパイル時間ヘルプは素晴らしいです!
次のポストでは、いくつかのインターナルとNullable注釈コンテキストを見ていきます.
Reference
この問題について(C経線の許容可能な参照型—null許容参照型への移行—パート1), 我々は、より多くの情報をここで見つけました https://dev.to/maartenba/nullable-reference-types-in-c-migrating-to-nullable-reference-types-part-1-2k3oテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol