C#4.0はオプションout
またはref
引数を許可しますか?
null
デフォルトの設定(私はPHPから来ています)を介してオプションの引数にかなり慣れ、引数の入力null
を続行するためのテストを(慣れ親しんだ人のためにpreg_match()
)とにかく、とにかく、技術的な点から理解すると、これは現在のところ不可能であり、そのPHPとC#はかなり比類のないものですが、それでも利用可能な「素晴らしい」ツールです。
C#4.0はオプションout
またはref
引数を許可しますか?
null
デフォルトの設定(私はPHPから来ています)を介してオプションの引数にかなり慣れ、引数の入力null
を続行するためのテストを(慣れ親しんだ人のためにpreg_match()
)とにかく、とにかく、技術的な点から理解すると、これは現在のところ不可能であり、そのPHPとC#はかなり比類のないものですが、それでも利用可能な「素晴らしい」ツールです。
回答:
すでに述べたように、これは単に許可されておらず、非常に理にかなっていると思います。ただし、さらに詳細を追加するために、C#4.0仕様のセクション21.1 からの引用を次に示します。
コンストラクター、メソッド、インデクサー、デリゲート型の仮パラメーターはオプションとして宣言できます。
fixed-parameter:
attributes opt parameter-modifier opt type identifier default-argument opt
default-argument:
= expression
- 固定パラメータとデフォルト引数であるオプションのパラメータに対し、固定パラメータなしのデフォルト引数がある必須パラメータ。
- 必須パラメーターは、formal-parameter-listのオプションパラメーターの後に表示することはできません。
- A
ref
またはout
パラメータが持つことができませんデフォルト引数を。
番号。
回避策は、out / refパラメーターがなく、現在のメソッドを呼び出すだけの別のメソッドでオーバーロードすることです。
public bool SomeMethod(out string input)
{
...
}
// new overload
public bool SomeMethod()
{
string temp;
return SomeMethod(out temp);
}
更新:C#7.0を使用している場合は、以下を簡素化できます。
// new overload
public bool SomeMethod()
{
return SomeMethod(out _); // declare out as an inline discard variable
}
(これを指摘してくれた@Oskar / @Reinerに感謝します。)
return SomeMethod(out string temp)
。もっとここを参照してください:blogs.msdn.microsoft.com/dotnet/2016/08/24/...
return SomeMethod(out _);
いいえ。ただし、次のように、オプションのパラメーターに汎用テンプレートクラスをメソッドで使用することは、別の優れた代替策です。
public class OptionalOut<Type>
{
public Type Result { get; set; }
}
その後、次のように使用できます。
public string foo(string value, OptionalOut<int> outResult = null)
{
// .. do something
if (outResult != null) {
outResult.Result = 100;
}
return value;
}
public void bar ()
{
string str = "bar";
string result;
OptionalOut<int> optional = new OptionalOut<int> ();
// example: call without the optional out parameter
result = foo (str);
Console.WriteLine ("Output was {0} with no optional value used", result);
// example: call it with optional parameter
result = foo (str, optional);
Console.WriteLine ("Output was {0} with optional value of {1}", result, optional.Result);
// example: call it with named optional parameter
foo (str, outResult: optional);
Console.WriteLine ("Output was {0} with optional value of {1}", result, optional.Result);
}
これを行う方法は実際にはC#で許可されています。これはC ++に戻り、むしろC#の優れたオブジェクト指向構造に違反します。
この方法は注意して使用してください!
オプションのパラメーターを使用して関数を宣言して記述する方法は次のとおりです。
unsafe public void OptionalOutParameter(int* pOutParam = null)
{
int lInteger = 5;
// If the parameter is NULL, the caller doesn't care about this value.
if (pOutParam != null)
{
// If it isn't null, the caller has provided the address of an integer.
*pOutParam = lInteger; // Dereference the pointer and assign the return value.
}
}
次に、次のような関数を呼び出します。
unsafe { OptionalOutParameter(); } // does nothing
int MyInteger = 0;
unsafe { OptionalOutParameter(&MyInteger); } // pass in the address of MyInteger.
これをコンパイルするには、プロジェクトオプションで安全でないコードを有効にする必要があります。これは、通常は使用すべきではない本当にハッキーなソリューションですが、奇妙で難解な、神秘的で管理にインスパイアされた決定の場合、C#でオプションの出力パラメーターが本当に必要な場合は、これでそれを実行できます。
ICYMI:ここに列挙されているC#7.0の新機能に含まれている「破棄」は、_の形式の出力パラメーターとして許可され、不要なパラメーターを無視できるようになりました。
p.GetCoordinates(out var x, out _); // I only care about x
PS「out var x」の部分と混同されている場合は、リンクの「Out Variables」に関する新機能もお読みください。
いいえ、Action
代わりにデリゲート(例:)を使用できます。
オプションの出力パラメーターが必要だと思った状況に直面したときのRobin Rの答えに一部触発され、代わりにAction
デリゲートを使用しました。私は彼のサンプルコードを借りてAction<int>
、違いと類似点を示すために使用するために修正しました:
public string foo(string value, Action<int> outResult = null)
{
// .. do something
outResult?.Invoke(100);
return value;
}
public void bar ()
{
string str = "bar";
string result;
int optional = 0;
// example: call without the optional out parameter
result = foo (str);
Console.WriteLine ("Output was {0} with no optional value used", result);
// example: call it with optional parameter
result = foo (str, x => optional = x);
Console.WriteLine ("Output was {0} with optional value of {1}", result, optional);
// example: call it with named optional parameter
foo (str, outResult: x => optional = x);
Console.WriteLine ("Output was {0} with optional value of {1}", result, optional);
}
これには、オプション変数が通常のintとしてソースに表示されるという利点があります(コンパイラーは、ユーザー定義クラスで明示的にラップするのではなく、クロージャークラスで変数をラップします)。
コンパイラーはAction
、関数呼び出しが終了する前にが呼び出されると想定できないため、変数を明示的に初期化する必要があります。
すべてのユースケースに適しているわけではありませんが、実際のユースケース(単体テストにデータを提供する関数、および新しい単体テストが戻り値に存在しない内部状態へのアクセスを必要とした場合)にはうまく機能しました。
これはどうですか?
public bool OptionalOutParamMethod([Optional] ref string pOutParam)
{
return true;
}
C#からパラメーターに値を渡す必要がありますが、これはオプションの参照パラメーターです。
[Optional]
注釈を無視します。これは役に立ちません。
void foo(ref int? n)
{
return null;
}