9

私は次のクラスを持っています:

public class Person
{
     public String Name { get; set; }
}

パラメータとしてPersonとを受け取るメソッドがあります。String

public void ChangeName(Person p, String name)
{
     p.Name = name;
}

Person参照によって渡されたため、渡されたインスタンスのを変更する必要がありますName

しかし、この方法は上記の方法よりも読みやすいですか?

public Person ChangeName(Person p, String name)
{
     p.Name = name;
     return p;
}
4

8 に答える 8

12

もっと読みやすいですか?いいえ。実際、あなたは彼らにもっと害を及ぼしているかもしれません。

Personオブジェクトを返すようにすることで、Personパラメーターを変更する代わりに、実際にはpに基づいて名前が異なる新しいPersonを作成していると思われる可能性があり、誰かがpが変更されないと誤って想定する可能性があります。

いずれにせよ、クラスに影響を与えないメソッドがある場合、それはおそらく静的であるはずです。これは、クラスに影響を与えないことを確実に知るのに役立ちます。値を返す必要がある場合にのみ、メソッドに値を返すようにします。

したがって、この方法に関する私の推奨事項は次のとおりです。

public static void ChangeName(Person p, String name)
{
    p.Name = name;
}
于 2011-03-11T06:05:57.080 に答える
1

まず、最初の例では、pは参照によって渡されていません。2番目の方法では、そうではない新しい参照を返していると信じ込ませます。ですから、2番目のものは最初のものよりも明確ではないと思います。

于 2011-03-11T07:21:13.563 に答える
1

読みやすくするために、次のいずれかを使用することをお勧めします。

public static void ChangeName(Person p, String name)
{
    p.Name = name;
}

public static Person WithName(Person p, String name)
{
    return new Person(p) { Name = name };    
}

2つ目は、Personオブジェクトを不変として扱い、オブジェクトの状態を変更しません。ChangeName関数は、入力オブジェクトの状態を明示的に変更します。2種類の方法を明確に区別することが重要だと思います。従うべき経験則は、メソッドはオブジェクトの状態を変更してはならず、同時にオブジェクトの状態を返すべきではないということです。

于 2011-03-11T06:58:18.440 に答える
1

どちらのアプローチにも正しい/間違ったものはありません。プログラムに必要なものによって異なります。

ユーザーは引数として渡された変数を代わりに使用することが常に可能であるため、メソッドに渡されたパラメーターを返す必要はほとんどありません。

ただし、最終的にこの実装をオーバーライドしたり、この実装を同様の署名を持つデリゲートを受け入れる別の関数に渡したりする柔軟性が得られます。次に、同じPersonオブジェクトを返さない他の実装を渡すことができます。

本当に柔軟性が必要な場合にのみ実行してください。

于 2011-03-11T06:10:35.723 に答える
0

私はあなたの2番目のアプローチがより読みやすいYAGNIではないと信じています。しかし、このように変更すると

public static class PersonExtensions 
{
public static Person ChangeName(this Person p, String name)
{
 p.Name = name;
 return p;
}

流暢なインターフェースのためのextensionmethodがあります

new Person().ChangeName("Peter Smith").SendEmail().Subject("Test Mail").Receiver("....)
于 2011-03-11T07:15:09.460 に答える
0

これは、値/参照によるパラメーターの受け渡しを理解するための最も信頼のおけるリファレンスです。

コードを見て、プロパティを使ってみませんか?

public string Name
{
   set {name = value;}
   get { return name; }
}

編集:自動実装されたプロパティ

public string Name
{
   set;
   get;
}
于 2011-03-11T07:21:46.210 に答える
0

あなたが説明した場合、私はどちらも言いません。この方法で何をしようとしているのかははっきりしていません。オブジェクトを使用してプロパティを設定するだけです。メソッドを実行パスに挿入すると、理解が複雑になり、Personオブジェクトとその基になる値に対する別の依存関係が作成されます。

あなたが投稿したコードに加えていくつかのデザインを含むメタ質問をしているなら、私はそれを見逃しています。

于 2011-03-11T06:09:12.170 に答える
0

最初のものの方が優れています。2番目のものは、pが不変であると信じさせる可能性があるためです。ただし、セッターを呼び出すだけなので、メソッド全体は役に立ちません。セッターに直接電話してみませんか?

于 2011-03-11T06:10:33.820 に答える