web-dev-qa-db-ja.com

C#8のnull不可の参照型を実行時にnullにすることはできますか?

Nullでない変数がnullを持たないという保証は本当にないようです。 nullにできないプロパティが1つあるクラスがあるとします。

public class Foo
{
    public Foo(string test)
    {
        Test = test;
    }
    public string Test {get;set;}
}

これはnullにできなくなったように見えるかもしれません。しかし、このクラスをnull可能コンテキストを使用しない別のライブラリーで参照する場合、そこにnullを送信することを止めるものはありません。

それは正しいですか、またはおそらくこれを確実にするいくつかの実行時チェックがありますか?

10

これは、MSが言っていることです( https://docs.Microsoft.com/en-us/dotnet/csharp/tutorials/upgrade-to-nullable-references#interfaces-with-external-code ) :

コードがnullableアノテーションコンテキストを有効にしてコンパイルされている場合でも、コンパイラはパブリックAPIへのすべての呼び出しを検証できません。さらに、null許容の参照型の使用をまだ選択していないプロジェクトによって、ライブラリが消費される場合があります。 nullを許容しない型として宣言した場合でも、パブリックAPIへの入力を検証します。

8
Dmitri Tsoy

独自のコードでも、そうすることを選択した場合、ヌル許容演算子を使用してnullを渡すことができます。 null!は、コンパイラのnull可能性分析に関する限り、nullではないと見なされます。

あなたは正しいです。新機能を使用していない他のコードは、このプロパティにnullを割り当てる可能性があります。それは単なるコンパイラのヒントである実行時チェックはありません。

ランタイムチェックが必要な場合は、いつでも自分で行うことができます。

public string Test { get; set{ if (value == null) throw new ArgumentNullException() } }

コードのmostでnullにならないことを保証できることに注意してください。トップレベルのパブリックAPIにガードを追加し、クラスが適切にシールされていることを確認するだけです。

もちろん、人々はまだリフレクションを使用してコードをf ***できますが、その後、

2
Milney

誰かがいつでもできる

var myFoo = new Foo(null);

ドメイン駆動設計を使用できるかもしれません

public class Foo
{
    public Foo(string test)
    {
         if (string.IsNullOrWhiteSpace(test))
             throw new ArgumentNullException(nameof(test));

         Test = test;
    }
    public string Test {get;private set;}
}
2
huMpty duMpty

Nullチェックを処理し、コードを読みやすくするために、nullオブジェクトデザインパターンをお勧めします。

詳細はこちら:

https://www.c-sharpcorner.com/article/null-object-design-pattern/

基本的には、同じインターフェイスから派生し、インスタンスがnullの新しいオブジェクトを作成する必要があります。

例:

public class NullExample : IExample  
{  
    private static NullExample _instance;  
    private NullExample()  
    { }  

    public static NullExample Instance  
    {  
        get {  
            if (_instance == null)  
                return new NullExample();  
            return _instance;  
        }  
    }  

    //do nothing methods  
    public void MethodImplementedByInterface1()  
    { }  

    public void MethodImplementedByInterface1()  
    { }  
}  

ヌルは避けられませんが、きれいにチェックできます。

0
Gauravsa