可変 - c# 配列 引数




C#を使用してパラメータとしてパラメータを渡す (7)

私は、同じシグネチャ(パラメータと戻り値)を持つ複数のメソッドを持っていますが、メソッドの名前とメソッドの内部が異なります。 メソッドの名前を渡して、渡されたメソッドを呼び出す別のメソッドに渡したいと思います。

public int Method1(string)
{
    ... do something
    return myInt;
}

public int Method2(string)
{
    ... do something different
    return myInt;
}

public bool RunTheMethod([Method Name passed in here] myMethodName)
{
    ... do stuff
    int i = myMethodName("My String");
    ... do more stuff
    return true;
}

public bool Test()
{
    return RunTheMethod(Method1);
}

このコードは機能しませんが、これは私がやろうとしていることです。 私が理解していないのは、パラメータを定義する必要があるのでRunTheMethodコードを記述する方法です。


Action Delegateを試すこともできます!

 public static int Method1(string mystring)
 {
      return 1;
 }

 public static int Method2(string mystring)
 {
     return 2;
 }

 public bool RunTheMethod(Action myMethodName)
 {
      myMethodName();
      return true;
 }

そして、あなたのメソッドを

RunTheMethod(() => Method1("MyString1"));

または

public static object InvokeMethod(Delegate method, params object[] args)
{
     return method.DynamicInvoke(args);
}

次にメソッドを呼び出します

Console.WriteLine(InvokeMethod(new Func<string,int>(Method1), "MyString1"));

Console.WriteLine(InvokeMethod(new Func<string, int>(Method2), "MyString2"));

RunTheMethodメソッドのパラメータとして、.net 3.5でFuncデリゲートを使用できます。 Funcデリゲートでは、特定の型の多数のパラメータを取り、特定の型の単一の引数を返すメソッドを指定できます。 ここでは動作する必要があります例:

public class Class1
{
    public int Method1(string input)
    {
        //... do something
        return 0;
    }

    public int Method2(string input)
    {
        //... do something different
        return 1;
    }

    public bool RunTheMethod(Func<string, int> myMethodName)
    {
        //... do stuff
        int i = myMethodName("My String");
        //... do more stuff
        return true;
    }

    public bool Test()
    {
        return RunTheMethod(Method1);
    }
}

ここでは、関数をパラメータとして渡す方法を理解するのに役立つ例を示します。

ページがあり、子ポップアップウィンドウを開きたいとします。 親ページには、子ポップアップテキストボックスに基づいて塗りつぶされるテキストボックスがあります。

ここでは、デリゲートを作成する必要があります。

Parent.cs //デリゲートの宣言public delegate void FillName(String FirstName);

今すぐあなたのテキストボックスを埋める関数を作成し、関数はデリゲートをマップする必要があります

//parameters
public void Getname(String ThisName)
{
     txtname.Text=ThisName;
}

ボタンをクリックすると、子ポップアップウィンドウを開く必要があります。

  private void button1_Click(object sender, RoutedEventArgs e)
  {
        ChildPopUp p = new ChildPopUp (Getname) //pass function name in its constructor

         p.Show();

    }

ChildPopUpコンストラクタで、親// pageの 'delegate type'のパラメータを作成する必要があります

ChildPopUp.cs

    public  Parent.FillName obj;
    public PopUp(Parent.FillName objTMP)//parameter as deligate type
    {
        obj = objTMP;
        InitializeComponent();
    }



   private void OKButton_Click(object sender, RoutedEventArgs e)
    {


        obj(txtFirstName.Text); 
        // Getname() function will call automatically here
        this.DialogResult = true;
    }

以下はパラメータなしの例です: http://en.csharp-online.net/CSharp_FAQ:_How_call_a_method_using_a_name_string : http://en.csharp-online.net/CSharp_FAQ:_How_call_a_method_using_a_name_string : http://en.csharp-online.net/CSharp_FAQ:_How_call_a_method_using_a_name_string

params: http : //www.daniweb.com/forums/thread98148.html#

基本的には、メソッドの名前とともにオブジェクトの配列を渡します。 両方をInvokeメソッドで使用します。

params Object []パラメータ


可能な限り完全な解決策を共有するために、3つの異なる方法を提示することになりますが、今は最も基本的な原則から始めます。

簡単な紹介

すべてのCLR( Common Language Runtime )言語(C#やVisual Basicなど)は、CLI( Common Language Interpreter )と呼ばれるVMのもとで動作し、CやC ++などのネイティブ言語よりも高いレベルでコードを実行します。 したがって、メソッドはコンパイルされたブロックではありませんが、CLRが認識して本体を引き出し、それをマシンコードのインライン命令に戻すために使用する構造化された要素です。 したがって、メソッドがパラメータとして渡すとは考えられません。メソッドはそれ自身では値を生成しないため、有効な式ではありません。 それで、あなたはデリゲートコンセプトをつまずくつもりです。

デリゲートとは何ですか?

デリゲートは、メソッドへのポインタを表します。 (上記のように)メソッドは値ではないため、CLR言語には特別なクラスがあります: Delegate 。 そのクラスは任意のメソッドをラップし、暗黙的にそのメソッドをキャストできます。

以下の使用例を見てください。

static void MyMethod()
{
    Console.WriteLine("I was called by the Delegate special class!");
}

static void CallAnyMethod(Delegate yourMethod)
{
    yourMethod.DynamicInvoke(new object[] { /*Array of arguments to pass*/ });
}

static void Main()
{
    CallAnyMethod(MyMethod);
}

3つの方法:

  • ウェイ1
    上記の例としてDelegate特別クラスを直接使用してください。 この解決法の問題は、メソッド宣言の型に型を限定することなく、引数を動的に渡す際にコードがチェックされないことです。

  • 方法2/3 Delegate特別クラスのほかに、 Delegate概念は、 delegateキーによって先行されるメソッドの宣言であるカスタムデリゲートに広がり、通常のメソッドのように動作します。 彼らはとてもチェックされ、あなたは " 完璧な "コードになるでしょう。

次の例を見てください:

delegate void PrintDelegate(string prompt);

static void PrintSomewhere(PrintDelegate print, string prompt)
{
    print(prompt);
}

static void PrintOnConsole(string prompt)
{
    Console.WriteLine(prompt);
}

static void PrintOnScreen(string prompt)
{
    MessageBox.Show(prompt);
}

static void Main()
{
    PrintSomewhere(PrintOnConsole, "Press a key to get a message");
    Console.Read();
    PrintSomewhere(PrintOnScreen, "Hello world");
}

この方法で独自のカスタムデリゲートを作成しないようにするもう1つの方法は、システムライブラリ内で宣言されたデリゲートを使用することです。

  • Actionは引数なしでvoidをラップしvoid
  • Action<T1>は1つの引数でvoidをラップしvoid
  • Action<T1, T2> 、2つの引数を持つvoidをラップしvoid
  • 等々...
  • Func<TR>は、引数なしのTR戻り型の関数をラップします。
  • Func<TR, T1>TR戻り値の型と引数を1つ持つ関数をラップします。
  • Func<TR, T1, T2>TR戻り型と2つの引数を持つ関数をラップします。
  • 等々...

(この後者の解決策は、多くの人が投稿したことです)。



public static T Runner<T>(Func<T> funcToRun)
{
    //Do stuff before running function as normal
    return funcToRun();
}

使用法:

var ReturnValue = Runner(() => GetUser(99));




delegates