C#을 사용하여 메서드를 매개 변수로 전달
매개 변수 유형과 반환 값은 같지만 이름과 블록은 다른 메서드가 여러 개 있습니다.전달된 메서드를 호출할 다른 메서드에 실행할 메서드의 이름을 전달하려고 합니다.
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 코드를 작성하는 방법을 이해할 수 없습니다.
당신은 할 수 .Func 3.5의 로 . 3합니다.RunTheMethod방법.그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);
}
}
대리인을 사용해야 합니다.이 경우 모든 방법은 다음을 수행합니다.string 변수를 합니다.int은 가장 이은가간표현다니됩게단으로 됩니다.Func<string, int>위임하다1따라서 코드는 다음과 같이 간단하게 변경할 수 있습니다.
public bool RunTheMethod(Func<string, int> myMethodName)
{
// ... do stuff
int i = myMethodName("My String");
// ... do more stuff
return true;
}
물론, 대의원들은 이보다 훨씬 더 많은 권한을 가지고 있습니다.예를 들어, C#을 사용하여 람다 식에서 대리자를 생성할 수 있으므로 다음과 같이 메서드를 호출할 수 있습니다.
RunTheMethod(x => x.Length);
그러면 다음과 같은 익명 함수가 생성됩니다.
// The <> in the name make it "unspeakable" - you can't refer to this method directly
// in your own code.
private static int <>_HiddenMethod_<>(string x)
{
return x.Length;
}
그리고 나서 그 대표자를 다음 사람에게 전달합니다.RunTheMethod방법.
이벤트 구독, 비동기 실행, 콜백 등 모든 종류의 작업에 대리인을 사용할 수 있습니다.특히 LINQ를 사용하고 싶다면 이에 대해 읽어볼 가치가 있습니다.딜러와 이벤트 간의 차이점에 대한 기사가 있지만, 어쨌든 유용할 수 있습니다.
1 이는 프레임워크의 일반 대리자 유형을 기반으로 하기 때문에 자신의 대리자 유형을 쉽게 선언할 수 있습니다.
public delegate int MyDelegateType(string value)
으로 지정합니다.MyDelegateType대신.
OP의 예에서:
public static int Method1(string mystring)
{
return 1;
}
public static int Method2(string mystring)
{
return 2;
}
Action Delegate를 시도할 수 있습니다!그런 다음 다음 다음을 사용하여 메소드를 호출합니다.
public bool RunTheMethod(Action myMethodName)
{
myMethodName(); // note: the return value got discarded
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"));
명확하고 완전한 답변을 제공하기 위해 세 가지 가능한 솔루션을 보여주기 전에 처음부터 시작하겠습니다.
간단한 소개
모든 .NET 언어(예: C#, F# 및 Visual Basic)는 시스템 코드보다 훨씬 높은 수준인 CIL(Common Intermediate Language)로 코드를 실행하는 VM인 CLR(Common Language Runtime) 위에서 실행됩니다.메소드는 기능 언어 및 JavaScript와 달리 어셈블리 서브루틴이 아니며 값도 아닙니다. 오히려 CLR이 인식하는 기호입니다.값이 아니므로 매개 변수로 전달할 수 없습니다..NET에 특별한 도구가 있는 이유입니다.즉, 대표자들.
대리인이 뭐죠?
대리자는 메서드에 대한 핸들을 나타냅니다(핸들이라는 용어는 포인터보다 선호되며 후자는 구현 세부사항입니다).메서드가 값이 아니기 때문에 .NET에 특별한 클래스가 있어야 합니다. 즉,Delegate모든 방법을 마무리합니다.이것을 특별하게 만드는 것은 소수의 클래스와 마찬가지로 CLR 자체가 구현해야 하며 단순히 .NET 언어로 클래스로 작성할 수 없다는 것입니다.
동일한 기본 개념의 세 가지 솔루션
유형 - 안전하지 않은 방법
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); }여기서 단점은 코드가 유형이 안전하지 않아 제약 조건 없이 동적으로 인수를 전달할 수 있다는 것입니다.
커스텀 방식
그 외에
Delegate한 클래스,은 사용자 되며, 는 " 특클래스개사정다딜, 딜러은자용의확러산니게됩에념수의▁preceded▁the▁by▁special다,,확니▁delegates,▁spreads산ations됩" 앞에 나오는 방법의 선언입니다. 이는 다음에 선행되는 방법의 선언입니다.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"); }표준 라이브러리의 방식
또는 .NET Standard의 일부인 대리자를 사용할 수 있습니다.
Action변수 없는 매개가없는경우변수▁a▁up를 끝으로 ▁wrapsvoid방법;Action<T1>을 마무리합니다.void가 type인 경우T1;Action<T1, T2>을 마무리합니다.void가지 의 파라미터가 두 가 지 매 변 유 의 형 방 법T1그리고.T2각다음과같다각같다▁respect,각.- 기타 등등;
Func<TR>변수 를 매개 변수 없는 함수로 합니다.TR반환 형식;Func<T1, TR>를 으함 마칩다니로 마무리합니다.TR및 유형의 변수 하는 경우T1;Func<T1, T2, TR>를 으함 마칩다니로 마무리합니다.TR및 유형의 두 가지 변수가 경우T1그리고.T2각각;- 등등.
그러나 이와 같이 미리 정의된 대리인을 사용하면 매개 변수 이름이 자동으로 설명되지 않으며 대리인 유형의 이름도 인스턴스가 수행해야 하는 작업에 대해 의미가 없습니다.그러므로, 그들의 목적이 완전히 자명하지 않은 상황에서 그것들을 사용하는 것을 자제하세요.
후자의 해결책은 가장 많은 사람들이 올린 것입니다.저는 또한 완전성을 위해 제 대답에 그것을 언급하고 있습니다.
솔루션에는 딜러가 참여하며, 딜러는 통화 방법을 저장하는 데 사용됩니다.대리인을 인수로 하는 방법을 정의합니다.
public static T Runner<T>(Func<T> funcToRun)
{
// Do stuff before running function as normal
return funcToRun();
}
그런 다음 상담 사이트에서 딜러에게 전달합니다.
var returnValue = Runner(() => GetUser(99));
다음을 사용해야 합니다.Func<string, int>delegate, 즉 인함취수를것하는나을다타니냅은대리것이를 취하는 .string 및 int설정:
public bool RunTheMethod(Func<string, int> myMethod)
{
// Do stuff
myMethod.Invoke("My String");
// Do stuff
return true;
}
그런 다음 다음 다음과 같이 호출합니다.
public bool Test()
{
return RunTheMethod(Method1);
}
받아들여진 답변이 절대적으로 옳지만, 저는 추가적인 방법을 제공하고 싶습니다.
저는 비슷한 질문에 대한 해결책을 찾기 위해 스스로 노력한 끝에 여기에 오게 되었습니다.프레임워크를 , 그 , ▁an▁,▁i▁items▁▁menu▁to▁driven▁applic▁to▁list원▁framework▁people▁wanted▁and▁building▁a▁generic있수▁as▁am▁plugin습▁the▁a▁menu했니▁actual다▁part▁be기▁of저를추할가▁it▁i▁add는▁able목에▁to록일러반플항,을Menu가 없는될 수 입니다.MenuUI . 를 추가하는 , 했을 때 수 일이었습니다.메뉴에 대한 일반적인 정보를 추가하는 것은 충분히 쉽지만 플러그인 개발자에게 메뉴를 클릭할 때 콜백을 만들 수 있는 충분한 자유를 허용하는 것은 어려운 일이었습니다.제가 휠과 일반 메뉴의 호출을 다시 발명하고 이벤트에서 콜백을 트리거하려 한다는 사실이 밝혀지기 전까지!
그래서 여러분이 깨닫기만 하면 간단한 해결책은 지금까지 저를 피했습니다.
필요한 경우 기본에서 상속된 현재 메서드 각각에 대해 별도의 클래스를 만들고 각 메서드에 이벤트 핸들러를 추가합니다.
다음은 함수를 매개 변수로 전달하는 방법을 더 잘 이해하는 데 도움이 되는 예제입니다.
상위 페이지가 있고 하위 팝업 창을 열려고 한다고 가정합니다.상위 페이지에는 하위 팝업 텍스트 상자를 기준으로 입력해야 하는 텍스트 상자가 있습니다.
여기서 대리자를 만들어야 합니다.
Parent.cs // 대표 선언 공개 대표 void FillName(문자열 이름);
이제 텍스트 상자를 채우고 딜러를 매핑하는 기능을 만듭니다.
//parameters
public void Getname(String ThisName)
{
txtname.Text=ThisName;
}
이제 버튼을 클릭하면 Child 팝업 창이 열립니다.
private void button1_Click(object sender, RoutedEventArgs e)
{
ChildPopUp p = new ChildPopUp (Getname) //pass function name in its constructor
p.Show();
}
ChildPopUp 생성자에서 부모 //페이지의 '대리인 유형' 매개 변수를 만들어야 합니다.
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;
}
메서드를 매개 변수로 전달하려면 다음을 사용합니다.
using System;
public void Method1()
{
CallingMethod(CalledMethod);
}
public void CallingMethod(Action method)
{
method(); // This will call the method that has been passed as parameter
}
public void CalledMethod()
{
Console.WriteLine("This method is called by passing it as a parameter");
}
전달된 메서드가 하나의 인수를 사용하여 값을 반환해야 하는 경우,Func그게 최선의 방법입니다.여기 예가 있습니다.
public int Method1(string)
{
// Do something
return 6;
}
public int Method2(string)
{
// Do something different
return 5;
}
public bool RunTheMethod(Func<string, int> myMethodName)
{
// Do stuff
int i = myMethodName("My String");
Console.WriteLine(i); // This is just in place of the "Do more stuff"
return true;
}
public bool Test()
{
return RunTheMethod(Method1);
}
여기에서 문서 읽기
그나매변개전메달아가서반않는경는우에지환하도무러것드수로를 사용할 수도 .Action전달된 메서드에 대해 최대 16개의 매개 변수를 지원합니다.여기 예가 있습니다.
public int MethodToBeCalled(string name, int age)
{
Console.WriteLine(name + "'s age is" + age);
}
public bool RunTheMethod(Action<string, int> myMethodName)
{
// Do stuff
myMethodName("bob", 32); // Expected output: "bob's age is 32"
return true;
}
public bool Test()
{
return RunTheMethod(MethodToBeCalled);
}
여기에서 설명서 읽기
다음은 매개 변수가 없는 예제입니다. http://en.csharp-online.net/CSharp_FAQ:_How_call_a_method_using_a_name_string
매개 변수 포함: http://www.daniweb.com/forums/thread98148.html #
기본적으로 메소드 이름과 함께 객체 배열을 전달합니다.그런 다음 둘 다 Invoke 메서드와 함께 사용합니다.
매개 변수개체[] 매개 변수
class PersonDB
{
string[] list = { "John", "Sam", "Dave" };
public void Process(ProcessPersonDelegate f)
{
foreach(string s in list) f(s);
}
}
두 번째 클래스는 스토리지 클래스를 사용하는 클라이언트입니다.PersonDB의 인스턴스를 만드는 Main 메서드가 있으며, 클라이언트 클래스에 정의된 메서드로 해당 개체의 Process 메서드를 호출합니다.
class Client
{
static void Main()
{
PersonDB p = new PersonDB();
p.Process(PrintName);
}
static void PrintName(string name)
{
System.Console.WriteLine(name);
}
}
누가 이것을 필요로 할지 모르겠지만 대리자와 람다를 보내는 방법을 잘 모를 경우 대리자를 사용하는 함수가 매개 변수를 삽입할 필요가 없을 때 반환 값만 있으면 됩니다.
따라서 다음과 같은 작업도 수행할 수 있습니다.
public int DoStuff(string stuff)
{
Console.WriteLine(stuff);
}
public static bool MethodWithDelegate(Func<int> delegate)
{
///do stuff
int i = delegate();
return i!=0;
}
public static void Main(String[] args)
{
var answer = MethodWithDelegate(()=> DoStuff("On This random string that the MethodWithDelegate doesn't know about."));
}
언급URL : https://stackoverflow.com/questions/2082615/pass-method-as-parameter-using-c-sharp
'programing' 카테고리의 다른 글
| data.frame에서 단일 열의 이름을 변경하는 방법은 무엇입니까? (0) | 2023.06.11 |
|---|---|
| 간단한 SQL 코드로 마리아DB의 NOCYLE(오라클) 계층 쿼리를 사용하여 CONNECT BY (0) | 2023.06.11 |
| Angular 2 NgForm에서 터치된 이벤트를 관찰하는 방법은 무엇입니까? (0) | 2023.06.11 |
| 판다의 다른 값을 기준으로 한 값 변경 (0) | 2023.06.11 |
| 미들웨어에서 Vuex로 상태가 업데이트되지 않습니까? (0) | 2023.06.11 |