43

C#4では、名前付き引数と呼ばれる機能が導入されました。これは、次のようなシナリオで特に役立ちます。

int RegisterUser(string nameFirst, string nameLast, string nameMiddle, string email)

名前付き引数を使用して強制する方法はありますか?たぶん、私が知らないメソッドまたはコンパイラスイッチに適用する属性はありますか?コードインスペクターツールで実行できると思いますが、他の方法があるかどうかを知りたいだけです。

ps

なぜそれが必要なのか、そしてなぜクラス/構造体を使用してオブジェクト初期化子を利用しないのかということに興味がある人のために、それが不可能なシナリオがあります。あなたのコントロールにないライブラリへの呼び出しや、あなたが従わなければならない奇妙なコード規約のように。

4

5 に答える 5

28

いいえ、C# 言語ではありません。すべてのパラメータが指定されている場合、常に位置パラメータを受け入れます。

これを強制するカスタム FxCop ルールまたはStyleCop ルールを作成できます。コメントで指摘されているように、関心のある StyleCop ルールである可能性があります (Kris に感謝します)。

于 2012-07-02T20:25:48.930 に答える
6

恥知らずなプラグでごめんなさい!メソッドの名前付き引数の使用を強制するRoslyn アナライザー
を実装しました。

したがって、RequireNamedArgs アナライザーをインストールし、名前付き引数で呼び出す必要があるメソッドの前に特別なコメントを追加すると、次のようになります。

//[RequireNamedArgs]
int RegisterUser(string nameFirst, string nameLast, string nameMiddle, string email)

呼び出し元が名前付きではなく位置引数を使用しようとすると、アナライザーはエラーを出力します。

実際に見てみましょう:ここに画像の説明を入力

やってみることにした場合は、自己責任で行ってください:)

于 2018-08-17T09:01:45.087 に答える
4

また、名前付き引数を強制する方法も探しました。オプションのパラメーターは危険な場合があります。特に、同じ型のパラメーターが複数ある場合は危険です。ほとんどの場合、オーバーロードはより安全な解決策ですが、多くの引数の組み合わせを取ることができるメソッドがある場合があるため、あらゆる可能性を考慮して 20 個のオーバーロードを作成するのはやり過ぎです。

引数に常に名前を付けることが最も重要な極端な状況では、コンストラクターを定義せずに引数クラスを作成します。あなたの場合、これを行うことができます:

public class UserRegistrationArguments
{
    public string nameFirst { get; set; }
    public string nameLast { get; set; }
    public string nameMiddle { get; set; }
    public string email { get; set; }
}

次のように呼び出します。

RegisterUser(new UserRegistrationArguments { nameFirst = "Bob", nameLast = "Slob" });

次のように単純化することもできます。

public class UserRegistrationArguments
{
    public string nameMiddle { get; set; }
    public string email { get; set; }
}

int RegisterUser(string nameFirst, string nameLast, UserRegistrationArguments args = null)

...そしてこれを行います:

RegisterUser("Bob", "Slob", new UserRegistrationArguments { nameMiddle = "Teh" }); 

このように、オプション パラメータは 1 つしかなく、それはオプション パラメータ用です。

編集: OPを正しく読んでいない可能性があります。オプションの引数を使用していませんか? そうでない場合、この回答はおそらく役に立ちません。

于 2016-01-13T23:01:16.250 に答える