8

C# では、最も純粋な意味で複数の戻り値が許可されているとしましょう。

string sender = message.GetSender();
string receiver = message.GetReceiver();

に圧縮:

string sender, receiver = message.GetParticipants();

その場合、実際にメソッド呼び出しを行うまで、メソッドの戻り値を理解する必要はありません。おそらく、どのような戻り値を扱っているかを教えてくれる Intellisense に頼っているのかもしれませんし、なじみのないクラスから必要なものを返すメソッドを探しているのかもしれません。

同様に、現在、C# には次のようなものがあります。

string receiver;
string sender = message.GetParticipants(out receiver);

ここで、GetParticipants の引数は出力文字列パラメーターです。ただし、これは上記とは少し異なります。これは、out パラメーターの結果を保持する変数を作成するコードを先取りするか、少なくとも戻って記述する必要があることを意味するためです。これは少し直感に反します。

私の質問は、開発者がメソッド呼び出しと同じ行でこの宣言を行うことを可能にする、現在の C# に構文糖衣があるかどうかです。次のようなことをすると、開発が(少し)より流動的になり、コードが読みやすくなると思います。

string sender = message.GetParicipants(out string receiver);

受信者がその場で宣言され、割り当てられたことを示すため。

4

10 に答える 10

9

いいえ、現在、これに関するシンタックス シュガーはありません。導入の意向も聞いていない。

私はoutパラメーターを頻繁に使用して、それが本当に重大な懸念事項であるとは言えません (C# チームに時間を費やしてもらいたい機能が他にもあります) が、少し面倒だとは思います。

于 2009-04-14T16:57:27.720 に答える
5

.NET 4 では、これに対処するタプルの概念が追加されます。残念ながら、C# 言語は、"destructuring bind" の言語サポートを提供しません。

于 2009-04-14T17:08:04.590 に答える
4

個人的には、パラメータを使い切るときに生じる不便さが好きです。私のメソッドが実際に本来あるべきことを実行しているかどうか、またはあまりにも多くの機能を詰め込んでいるかどうかを考えるのに役立ちます。そうは言っても、おそらくC#4.0 /.Net4での動的型付けはあなたの懸念のいくつかに対処するでしょう。

dynamic participant = message.GetParticipants();

var sender = participant.Sender;
var recipient = participant.Recipient;

どこ

public object GetParticipants()
{
     return new { Sender = ..., Recipient = ... };
}
于 2009-04-14T17:16:30.963 に答える
2

または同様のものを返すこともできますTuple<T,U>。ただし、2 つの文字列を返したいので、混乱する可能性があります。

私は非常に便利なBclExtras ライブラリの Tuples 構造体を使用しています (SO で見つけました、JaredPar に感謝します!)。

于 2009-04-14T17:10:13.397 に答える
2

そのような機能は存在しないと思いますが、perl の配列と同様の方法で実装されていれば、実際に役立つ可能性があります。

perl では、括弧内の変数のリストに配列を割り当てることができます。たとえば、これを行うことができます

($user, $password) = split(/:/,$data);
于 2009-04-14T17:24:59.323 に答える
2

これが私を最も悩ませているところ:パラメーターDateTime.TryParseを取らない(たとえば)のオーバーロードがないため、out書くことはできません

if (DateTime.TryParse(s, out d))
{
   return new ValidationError("{0} isn't a valid date", s);
}

宣言せずにdoutこれがパラメーターの問題なのか、メソッドの実装方法の問題なのかはわかりませんが、TryParse面倒です。

于 2009-04-14T18:18:04.780 に答える
0

varすべての複数の戻り値を同じ型に制限したい場合を除き (実用的ではない可能性があります)、せいぜい明示的な型ではなく使用する必要があります。また、変数のスコープを制限することになります。現在、より高いスコープで変数を宣言し、out パラメーターで初期化できます。このアプローチでは、変数は割り当てと同じブロックでスコープ外になります。明らかに、これは場合によっては使用できますが、一般的なルールとしてこれを強制したくありません。outもちろん、' ' オプションをそのままにしておくこともできますが、人々はいずれかの方法でコーディングする可能性があります。

于 2009-04-14T16:55:46.460 に答える
-1

次のコードを試してください

Participants p = message.GetParticipants();
log(p.sender,p.receiver);
于 2009-04-14T17:04:23.600 に答える
-1

これはあなたが望むものではないと思います。気に入ったコードに出くわしたことがあるかもしれません。しかし、変数がパラメータリストに導入されたためにどこからともなく飛び出すことは、個人的な悪夢です(私にとって:))

複数の戻り値には、移植性/保守性の点で重大な欠点があります。2 つの文字列を返す関数を作成し、3 つの文字列を返すようにするには、この関数を使用するすべてのコードを変更する必要があります。ただし、返されたレコード タイプは通常、このような一般的なシナリオでうまく機能します。

あなたはパンドラの箱を開けているかもしれません;-)

行圧縮の場合:

string s1, s2; s1 = foo.bar(s2);

行は任意の長さにできるため、一般的なものを 1 つにまとめることができます。セミコロンと一緒に暮らすようにしてください。

于 2009-04-14T17:07:45.493 に答える