554

注:この質問は、C# がまだオプションのパラメーターをサポートしていなかった時点 (つまり、C# 4 より前) に出されました。

C# クラスからプログラムによって生成される Web API を構築しています。クラスにはメソッドがGetFooBar(int a, int b)あり、API には のGetFooBarようなクエリ パラメータを取るメソッドがあります&a=foo &b=bar

クラスは、C# 言語ではサポートされていないオプションのパラメーターをサポートする必要があります。最善のアプローチは何ですか?

4

23 に答える 23

1203

次のように機能する C# 4.0 のオプションのパラメーターについて誰も言及していないことに驚きました。

public void SomeMethod(int a, int b = 0)
{
   //some code
}

編集:質問がされた時点で、C# 4.0 が存在しなかったことは知っています。しかし、この質問は「C#のオプションの引数」でGoogleでまだ1位にランクされているので、この回答はここにある価値があると思いました。ごめん。

于 2010-07-27T12:51:10.473 に答える
137

別のオプションは、 params キーワードを使用することです

public void DoSomething(params object[] theObjects)
{
  foreach(object o in theObjects)
  {
    // Something with the Objects…
  }
}

のように呼ばれ...

DoSomething(this, that, theOther);
于 2008-10-14T02:03:22.913 に答える
80

C# では、通常、メソッドの複数の形式を使用します。

void GetFooBar(int a) { int defaultBValue;  GetFooBar(a, defaultBValue); }
void GetFooBar(int a, int b)
{
 // whatever here
}

更新: これは、C# 2.0 でデフォルト値を実行した方法でした。私が現在取り組んでいるプロジェクトでは、オプションのパラメーターを直接サポートするようになった C# 4.0 を使用しています。これは、私が自分のコードで使用した例です。

public EDIDocument ApplyEDIEnvelop(EDIVanInfo sender, 
                                   EDIVanInfo receiver, 
                                   EDIDocumentInfo info,
                                   EDIDocumentType type 
                                     = new EDIDocumentType(EDIDocTypes.X12_814),
                                   bool Production = false)
{
   // My code is here
}
于 2008-10-14T02:00:02.077 に答える
53

このサイトから:

http://www.tek-tips.com/viewthread.cfm?qid=1500861&page=1

C# では [Optional] 属性を使用できます (VB から、ただし C# では機能しません)。したがって、次のようなメソッドを使用できます。

using System.Runtime.InteropServices;
public void Foo(int a, int b, [Optional] int c)
{
  ...
}

API ラッパーでは、オプションのパラメーター (ParameterInfo p.IsOptional) を検出し、デフォルト値を設定します。目標は、パラメーター名に「オプション」を含めるなどの決まり文句に頼ることなく、パラメーターをオプションとしてマークすることです。

于 2008-10-14T01:57:23.423 に答える
32

メソッドのオーバーロードを使用できます...

GetFooBar()
GetFooBar(int a)
GetFooBar(int a, int b)

メソッドのシグネチャに依存します。私が示した例には、「int a」メソッドと同じシグネチャがあるため、「int b」のみのメソッドがありません。

Nullable 型を使用できます...

GetFooBar(int? a, int? b)

次に、a.HasValue を使用して、パラメーターが設定されているかどうかを確認できます。

別のオプションは、「params」パラメーターを使用することです。

GetFooBar(params object[] args)

名前付きパラメーターを使用する場合は、それらを処理する型を作成する必要がありますが、Web アプリには既にこのようなものがあると思います。

于 2008-10-14T02:03:13.320 に答える
27

C#4.0では、オプションのパラメーターを心配することなく使用できます。次のような方法がある場合:

int MyMetod(int param1, int param2, int param3=10, int param4=20){....}

メソッドを呼び出すときは、次のようなパラメーターをスキップできます。

int variab = MyMethod(param3:50; param1:10);

C#4.0は、「名前付きパラメーター」と呼ばれる機能を実装しています。実際には、パラメーターを名前で渡すことができます。もちろん、パラメーターは任意の順序で渡すことができます:)

于 2011-02-22T09:52:50.387 に答える
20

ハローオプショナルワールド

ランタイムにデフォルトのパラメーター値を提供させたい場合は、リフレクションを使用して呼び出しを行う必要があります。この質問に対する他の提案ほど良くはありませんが、VB.NET と互換性があります。

using System;
using System.Runtime.InteropServices;
using System.Reflection;

namespace ConsoleApplication1
{
    class Class1
    {
        public static void sayHelloTo(
            [Optional,
            DefaultParameterValue("world")] string whom)
        {
            Console.WriteLine("Hello " + whom);
        }

        [STAThread]
        static void Main(string[] args)
        {
            MethodInfo mi = typeof(Class1).GetMethod("sayHelloTo");
            mi.Invoke(null, new Object[] { Missing.Value });
        }
    }
}
于 2008-10-14T10:58:22.803 に答える
9

私はスティーブンベイヤーに同意します。ただし、これは Web サービスであるため、同じメソッドの複数のバージョンを使用するよりも、エンド ユーザーが Web メソッドの 1 つの形式のみを使用する方が簡単です。この状況では、Nullable 型はオプションのパラメーターに最適だと思います。

public void Foo(int a, int b, int? c)
{
  if(c.HasValue)
  {
    // do something with a,b and c
  }
  else
  {
    // do something with a and b only
  }  
}
于 2008-10-14T02:09:14.710 に答える
7

オプションのパラメータはメソッド用です。クラスにオプションの引数が必要で、次の場合:

  • c# 4.0 の使用: クラスのコンストラクターでオプションの引数を使用します。これは、メソッドで行われることに近いため、覚えやすいため、私が好む解決策です。例を次に示します。

    class myClass
    {
        public myClass(int myInt = 1, string myString =
                               "wow, this is cool: i can have a default string")
        {
            // do something here if needed
        }
    }
    
  • c#4.0 より前のバージョンの c# を使用する場合: コンストラクター チェーン (:this キーワードを使用) を使用する必要があります。単純なコンストラクターは "マスター コンストラクター" につながります。例:

    class myClass
    {
        public myClass()
        {
        // this is the default constructor
        }
    
        public myClass(int myInt)
            : this(myInt, "whatever")
        {
            // do something here if needed
        }
        public myClass(string myString)
            : this(0, myString)
        {
            // do something here if needed
        }
        public myClass(int myInt, string myString)
        {
            // do something here if needed - this is the master constructor
        }
    }
    
于 2011-05-23T17:16:32.473 に答える
3

stephen が述べたように、C# でこれを処理する一般的な方法は、メソッドをオーバーロードすることです。さまざまなパラメーターを使用してメソッドの複数のバージョンを作成することにより、オプションのパラメーターを効果的に作成できます。パラメーターが少ないフォームでは、通常、メソッドの呼び出しですべてのパラメーターがデフォルト値を設定してメソッドのフォームを呼び出します。

于 2008-10-14T02:03:53.193 に答える
0

delegate念のため、コールバック (または) をオプションのパラメーターとして渡したい場合は、この方法で行うことができます。

オプションのコールバック パラメータ:

public static bool IsOnlyOneElement(this IList lst, Action callbackOnTrue = (Action)((null)), Action callbackOnFalse = (Action)((null)))
{
    var isOnlyOne = lst.Count == 1;
    if (isOnlyOne && callbackOnTrue != null) callbackOnTrue();
    if (!isOnlyOne && callbackOnFalse != null) callbackOnFalse();
    return isOnlyOne;
}
于 2015-06-17T13:46:48.633 に答える
0

7 つのパラメーターを受け取る Web サービスを作成します。それぞれは、この Web サービスによってラップされた sql ステートメントに対するオプションのクエリ属性です。したがって、オプションではないパラメーターに対する2つの回避策が思い浮かびます...どちらもかなり貧弱です:

method1(param1, param2, param 3, param 4, param 5, param 6, param7) method1(param1, param2, param3, param 4, param5, param 6) method 1(param1, param2, param3, param4, param5, param7) )... 写真を見始めます。この方法は狂気です。組み合わせが多すぎる。

次に、扱いにくいように見えるが機能するはずのより簡単な方法について説明します。

これは 1 つのメソッド呼び出しであり、すべてのパラメーターの値が必要であり、その内部で各ケースを処理します。インターフェイスからの使用方法も明確です。

ハックですが、うまくいきます。

于 2009-12-22T00:40:52.117 に答える
0

パーティーに少し遅れましたが、私はこの質問に対する答えを探していて、最終的にこれを行う別の方法を見つけました. Web メソッドのオプションの引数のデータ型を XmlNode 型として宣言します。オプションの arg が省略された場合、これは null に設定されます。存在する場合は、arg.Value を呼び出すことで文字列値を取得できます。つまり、

[WebMethod]
public string Foo(string arg1, XmlNode optarg2)
{
    string arg2 = "";
    if (optarg2 != null)
    {
        arg2 = optarg2.Value;
    }
    ... etc
}

このアプローチの良い点は、ws 用に生成された .NET のホームページに引き続き引数リストが表示されることです (ただし、テスト用の便利なテキスト入力ボックスは失われます)。

于 2009-11-17T01:50:33.137 に答える
0

デフォルトのパラメーターの代わりに、渡されたクエリ文字列から辞書クラスを構築してみませんか.. asp.net フォームがクエリ文字列を操作する方法とほぼ同じ実装です。

すなわち Request.QueryString["a"]

これにより、ファクトリ/ボイラープレート コードからリーフ クラスが切り離されます。


また、ASP.NETを使用した Web サービスも確認してください。Web サービスは、C# クラスの属性を介して自動的に生成される Web API です。

于 2008-10-14T02:09:07.347 に答える
0

VB.Net 2.0 Web サービスでこれを行う必要がありました。パラメータを文字列として指定してから、必要なものに変換しました。オプションのパラメーターが空の文字列で指定されました。最もクリーンなソリューションではありませんが、うまくいきました。発生する可能性のあるすべての例外をキャッチするように注意してください。

于 2011-01-03T20:21:22.123 に答える
-4

こちらもお試しいただけます
Type 1
public void YourMethod(int a=0, int b = 0) { //some code }


タイプ2
public void YourMethod(int? a, int? b) { //some code }

于 2018-03-23T04:30:48.807 に答える