1

オブジェクトをパラメータとして受け入れるクラスによって変更されているオブジェクトのプロパティを変更するための次の2つの提案の最良の方法は何ですか?

  1. クラスにオブジェクトを処理させ、値を返し、それをオブジェクトに割り当てます

また。

  1. refキーワードを使用してオブジェクトを渡し、実際には何も返さずにクラスにオブジェクトを修正させます。

たとえば、名と名前のPersonオブジェクトと、フルネームを作成する2つの異なる方法があります。

どちらが最善の方法ですか?

public static void Main()
{
    Person a = new Person {  FirstName = "John", LastName = "Smith" };
    Person b = new Person { FirstName = "John", LastName = "Smith" };

    NameProcesser np = new NameProcesser();

    // Example A
    a.FullName = np.CreateFullNameA(a);

    // Example B
    np.CreateFullNameB(ref b);
}

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string FullName { get; set; }
}


public class NameProcesser
{
    public string CreateFullNameA(Person person)
    {
        return person.FirstName + " " + person.LastName;
    }

    public void CreateFullNameB(ref Person person)
    {
        person.FullName = person.FirstName + " " + person.LastName;
    }
}
4

4 に答える 4

2

必要ありませんref。メソッド内のオブジェクトを変更するだけです。

参照型がパラメーターとして渡される場合、値ではなく「参照によって」渡されます。したがって、変更すると、実際には元のオブジェクトが変更されます。refなどの値の型を渡す場合にのみ必要ですint

実際に起こっているのは、元のオブジェクトへの内部「ポインター」が値によって渡されているためです。

于 2012-09-26T20:25:47.377 に答える
1

まず最初に

あなたが言及しているという事実はref、基本的な概念が欠けていることを示唆しています。つまり、オブジェクトへの参照にアクセスできるコードは、定義により、実際のオブジェクトにアクセスできます。

パラメータを使用する唯一の考えられる使用シナリオは、refその参照を他のオブジェクトまたは に設定する場合ですnull

使用しない場合ref(またはその点については、ここoutで違いを参照してください)、実際には引数を値で渡します。つまり、引数のコピーが作成されます。

これは、パラメーターが値型(int、long、float など) であるか参照型(任意のクラスのインスタンスへの参照)であるかに応じて、2 つのことを意味します。

パラメータが値型の場合、そのコピーが作成されます。コピーはそのメソッドのスコープにのみ制限されるため、メソッドは必要なことを何でも実行できます。

ただし、パラメーターが参照型の場合 (あなたのPerson場合と同様)、参照自体のみがコピーされます。基になるオブジェクトは同じです。ここが大きな違いです。ただし、メソッド内で使用できる参照は元の参照のコピーであることを覚えておいてくださいnull。メソッドが戻ると、その参照は消え、元の参照はそのまま残ります。

そうは言っても

他の人があなたに言ったように、実際に使用する必要はありませんref

さらに、名前と姓を連結するなどの些細なケースを扱っている限り、オブジェクト自体にそれをさせます (Slapout が行ったのとまったく同じように)。

そのような必要が生じた場合、後で責任を分離する時間は常にあります。

また、そのような些細なタスクに別のクラスを用意することも、直感に反すると見なされる可能性があることを考慮してください。これが手元のコードだとしましょう:

var p = new Person() { FirstName = "John", LastName = "Smith"} ;

Console.WriteLine(p.FullName);

FullName私がそうするとき、私は常に何か意味のあるもの (つまり、「ジョン・スミス」) を返すことを完全に期待しています。

代わりに、両方のアプローチで、を呼び出すのを忘れた場合 (そして私がCreateFullName忘れた場合) はどうなりますか?

特定の懸念事項を別のクラスに移動する必要がある場合は、プロパティのgetメソッド内に隠します。

そうすれば、人々はあなたが書いたクラスの基盤について知る必要がなくなり、テストも可能になります。

于 2012-09-26T21:04:40.103 に答える
0

どちらも - そして「ref」は必要ありません - ただ使用してください:

public void CreateFullNameB(Person person) 
{ 
    person.FullName = person.FirstName + " " + person.LastName; 
} 
于 2012-09-26T20:24:59.607 に答える
0

まず、メソッドを別のクラスに分離する唯一の理由は、そのメソッドにデータベースやネットワーク アクセスなどの依存関係があるかどうかです。それ以外の場合、その単純なメソッドはPersonクラスのプロパティにする必要があります。

また、オブジェクト全体をメソッドに渡す唯一の理由は、オブジェクトデータがそのメソッド内で広く使用されている場合です。それ以外の場合は、FirstName と LastName をパラメーターとして渡して結果を返すことをお勧めします。

ref内容を変更するために修飾子を使用してクラスを渡す必要はありません。ref は、メソッドが新しいインスタンスへの参照を使用してパラメーターを割り当てたい場合にのみ必要です。

説明した例では、2 つのオプションから選択する場合、結合が少なくなり、ロジックがデータ表現から分離されるため、戻り値の方が優れています。ただし、エンティティのプロパティをほとんど更新できない場合は、オブジェクトを渡す方が適切です。

于 2012-09-26T20:29:56.957 に答える