質問
電話をかけています:
myResult = MakeMyCall(inputParams, out messages);
しかし、私は実際にメッセージを気にしません。それが入力パラメーターだった場合、私は気にしませんでしたが、nullを渡すだけです。それが帰りだったら、私は気にしませんでした。
outで同様のことを行う方法はありますか、それとも無視する変数を宣言する必要がありますか?
解決
C#7.0以降では、パラメータの事前宣言と無視を避けることができます。
public void PrintCoordinates(Point p)
{
p.GetCoordinates(out int x, out int y);
WriteLine($"({x}, {y})");
}
public void PrintXCoordinate(Point p)
{
p.GetCoordinates(out int x, out _); // I only care about x
WriteLine($"{x}");
}
出典: https ://blogs.msdn.microsoft.com/dotnet/2017/03/09/new-features-in-c-7-0/
他のヒント
無視する変数を宣言する必要があります。これは、実際の解析値を気にせずにユーザー入力の妥当性をテストするために使用される場合(たとえば、数値として解析できるか)、TryParse(またはTryWhatever)パターンの場合に最も一般的です。
単語<!> quot; dispose <!> quot;を使用しました。質問では、残念なことですが、outパラメーターがIDisposableを実装する型である場合、値を受け取っても所有権が付与されないと明示的に記載されていない限り、必ずDisposeを呼び出す必要があります。ただし、使い捨てのout
パラメータを使用したメソッドを見たことは覚えていないので、これが単なる不幸な言葉の選択になったことを望んでいます。
残念ながら、メソッドを設定するにはメソッドが必要なので、何かを渡す必要があります。そのため、設定に必要なメソッドが爆発するため、null
を送信できません。
さを隠す1つの方法は、次のようにout
パラメーターを実行する別のメソッドでメソッドをラップすることです。
String Other_MakeMyCall(String inputParams)
{
String messages;
return MakeMyCall(inputParams, out messages);
}
その後、不要なOther_MakeMyCall
パラメータをいじらずに<=>を呼び出すことができます。
元の関数が次のように宣言されている場合:
class C
{
public Result MakeMyCall(Object arg, out List<String> messages);
}
次のような拡張メソッドを宣言できます:
static class CExtension
{
public static Result MakeMyCall(this C obj, Object arg)
{
List<String> unused;
return obj.MakeMyCall(arg, out unused);
}
}
拡張メソッドは、outパラメーターをオプションにするオーバーロードのように動作します。
Visual Basicコンパイラは、ダミー変数を作成してこれを行います。 Microsoftに良いアイデアを納得させることができれば、C#でそれを行うことができます。
messages
のクラスがIDisposable
を実装する場合、無視しないでください。次のようなアプローチを検討してください(しばらくの間C#を書いていないため、構文的には正しくないかもしれません):
using (FooClass messages) {
myResult = MakeMyCall(inputParams, messages);
}
using
ブロックの外側になると、<=>は自動的に破棄されます。
outパラメーターに変数を渡す必要があります。渡す前に変数を初期化する必要はありません:
MyMessagesType messages;
myResult = MakeMyCall(inputParams, out messages);
通常、呼び出し後の「メッセージ」は無視できます-「メッセージ」が何らかのシステムリソースの使用などの理由で破棄する必要がない限り、その場合はDispose()を呼び出す必要があります:
messages.Dispose();
かなりの量のメモリを使用する可能性があり、しばらくスコープ内に留まる場合、参照型の場合はnullに設定し、値型の場合は新しいデフォルトインスタンスに設定する必要があります。ガベージコレクターがメモリを再利用できること:
messages = null; // Allow GC to reclaim memory for reference type.
messages = new MyMessageType(); // Allow GC to reclaim memory for value type.
この場合、DeleteメソッドまたはRemoveメソッドを持たないConcurrentDictionaryの汎用拡張メソッドを作成しました。
//Remove item from list and ignore reference to removed item
public static void TryRemoveIgnore<K,T>(this ConcurrentDictionary<K,T> dictionary, K key)
{
T CompletelyIgnored;
dictionary.TryRemove(key, out CompletelyIgnored);
}
ConcurrentDictionaryのインスタンスから呼び出された場合:
ClientList.TryRemoveIgnore(client.ClientId);