web-dev-qa-db-ja.com

C#-コンストラクターまたはプロパティを介してDTOを初期化しますか?

たとえばREST-APIを介したデータ転送に使用されるプレーンオブジェクトのプロパティを初期化する推奨アプローチがあるかどうか疑問に思いました。

ここに私が考えることができる2つの変種があります:

public class Dto
{
    public string Name { get; set; }
    public int Number { get; set; }
}

new Dto {
    Name = actualName,
    Number = actualNumber
};


vs


public class Dto
{
    public string Name { get; private set; }
    public int Number { get; private set; }

    public Dto(string name, int number)
    {
        Name = name;
        Number = number;
    }
}

new Dto(actualName, actualNumber);
or
new Dto(name: actualName,
        number: actualNumber);

最初に行くのは、それがより短く、維持するために必要な作業が少ないためです。ただし、新しく追加されたプロパティは、DTOを満たすユーザーによって見落とされる可能性があります。また、オブジェクトが不変にならないことも認識していますが、これはDTOにすぎないため、個人的にはそれほど重要ではないと思います。

7
AyCe

私の考えは、オブジェクトがデータを転送する手段として機能する場合(したがって、純粋にoutput/inputの意味で)、オブジェクトを変更可能にする必要がない場合は変更できないようにすることと、このように投げると読みやすさを上書きします。論理は、パブリックセッターが存在しないことで、クラスがどのような目的で機能するかを示し、したがって、単純な構文よりも読みやすいということです。

つまり、クラスは2番目のクラスのようになります。

_public class Dto
{
    public string Name { get; private set; }
    public int Number { get; private set; }

    public Dto(string name, int number)
    {
        Name = name;
        Number = number;
    }
}
_

率直に言って、読みやすさの観点からすると、new Dto(actualName, actualNumber);はそれほど悪くありません。

7
Neil

あなたは具体的なクラスだけを見ています。インターフェイスを追加して、ビューを拡大します。

このインターフェースには、セッターなしの読み取り専用プロパティがあります。一部のメソッドがインスタンスを受信したが、インターフェースしか認識していない場合、インスタンスを変更することはできません。しかし、インスタンスが作成される場所では、具象型がわかっているため、パラメーター化されたコンストラクター(わかりやすくするため)またはパブリックセッター(シリアル化フレームワークで必要な場合)を使用できます。

インターフェイスにセッターを追加しないでください。インスタンス作成の領域外で可変性が発生します。

1
Bernhard Hiller

DTOが有用であるためにはシリアル化可能である必要があり、シリアル化可能の要件の1つはデフォルトのパブリックコンストラクターを持つことです(シリアライザーはパラメーターを取るコンストラクターの呼び出し方法を知らないため)。

デフォルトのパブリックコンストラクタでは、プロパティをデフォルト値で初期化する必要があります。インスタンスに逆シリアル化すると、シリアル化された表現に存在しないプロパティには、これらのデフォルト値が含まれます。

0
bikeman868