web-dev-qa-db-ja.com

オブジェクトを作成する最良の方法

これは非常に愚かで初歩的な質問のようですが、グーグルで検索しようとしましたが、満足のいく答えが見つかりませんでした。

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public Person(){}
    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }
    //Other properties, methods, events...
}

私の質問は、このようなクラスがある場合、オブジェクトを作成する最良の方法は何ですか?

Person p=new Person("abc",15)

[〜#〜]または[〜#〜]

Person p=new Person();
p.Name="abc";
p.Age=15;

これら2つの方法の違いは何ですか?オブジェクトを作成する最良の方法は何ですか?

25
DevT

immutableオブジェクトが必要かどうかを決定します。

クラスにpublicプロパティを配置すると、コード内のすべてのインスタンスの状態を毎回変更できます。したがって、クラスは次のようになります。

_public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public Person(){}
    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }
    //Other properties, methods, events...
}
_

その場合、Person(string name, int age)コンストラクターはあまり役に立ちません。

2番目のオプションは、immutableタイプを実装することです。例えば:

_public class Person
{
    public string Name { get; private set; }
    public int Age { get; private set; }

    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }
    //Other properties, methods, events...
}
_

これで、作成時にインスタンスの状態onceを設定するコンストラクターが作成されました。現在、プロパティのセッターはprivateであるため、オブジェクトのインスタンス化後に状態を変更することはできません。

ベストプラクティスは、可能な場合は常にクラスを不変として定義することです。不変クラスの利点を理解するには、この 記事 を読むことをお勧めします。

35
davioooh

本当に要件に依存しますが、最近、少なくとも1つのベアコンストラクターが定義されたクラスの傾向を見てきました。

コンストラクターを介してパラメーターをポストする利点は、インスタンス化後にこれらの値を信頼できることです。欠点は、ベアコンストラクターでオブジェクトを作成できると予想されるライブラリで、より多くの作業を行う必要があることです。

私の個人的な好みは、裸のコンストラクタを使用して、宣言の一部としてプロパティを設定することです。

Person p=new Person()
{
   Name = "Han Solo",
   Age = 39
};

これにより、「クラスに必要なコンストラクターがない」という問題が回避され、さらにメンテナンスが軽減されます(コンストラクターを変更せずにより多くのものを設定できます)。

10

本当に最善の方法はありません。初期化中にコンストラクターに渡されたパラメーターを使用して追加の処理を実行する場合、またはコンストラクターを呼び出した直後に一貫した状態を確保する場合を除き、どちらもまったく同じです。その場合は、最初のものを優先してください。

ただし、読みやすさ/保守性の理由から、パラメーターが多すぎるコンストラクターを作成しないでください。

この場合、両方が行います。

6
xlecoustillier

私の謙虚な意見では、これは引数がオプションであるかどうかを決定するだけの問題です。 Personオブジェクトが(論理的に)NameとAgeなしで存在してはならない場合、それらはコンストラクタで必須です。それらがオプションである場合(つまり、それらが存在しないことはオブジェクトの良好な機能に対する脅威ではない)、セッターを使用します。

コンストラクター注入に関するSymfonyのドキュメントからの引用です:

コンストラクター注入を使用することには、いくつかの利点があります。

  • 依存関係が要件であり、それなしではクラスが機能できない場合、コンストラクターを介してクラスを挿入すると、クラスが使用されたときにクラスが存在しないことを確認できます。
  • コンストラクターは、オブジェクトの作成時に一度しか呼び出されないため、オブジェクトの存続期間中に依存関係が変更されないことを確認できます。

これらの利点は、コンストラクター注入がオプションの依存関係の処理に適していないことを意味します。また、クラス階層と組み合わせて使用​​することはより困難です。クラスがコンストラクター注入を使用する場合、それを拡張してコンストラクターをオーバーライドすると問題が発生します。

(Symfonyは最も人気があり尊敬されているphpフレームワークの1つです)

6
Hugo Mota

コードが少ないほど効率的であると考える場合は、構造関数を使用する方が適切です。次のようなコードも使用できます。

Person p=new Person(){
Name='abc',
Age=15
}
4
roast_soul

要件に依存しますが、最も効果的な作成方法は次のとおりです。

 Product obj = new Product
            {
                ID = 21,
                Price = 200,
                Category = "XY",
                Name = "SKR",
            };
0

または、データファイルを使用して、多数の人物オブジェクトをリストまたは配列に入れることができます。これにはSystem.IOを使用する必要があります。また、オブジェクトに関するすべての情報を含むデータファイルが必要です。

その方法は次のようになります。

static void ReadFile()
{
    using(StreamWriter writer = new StreamWriter(@"Data.csv"))
    {
        string line = null;
        line = reader.ReadLine();
        while(null!= (line = reader.ReadLine())
                {
                    string[] values = line.Split(',');
                    string name = values[0];
                    int age = int.Parse(values[1]);
                }
        Person person = new Person(name, age);
    }
}
0
Chimmy