동일한 서명 (매개 변수 및 반환 값)을 가진 여러 가지 방법이 있지만 이름과 방법의 내부가 다릅니다. 전달 된 메소드를 호출하는 다른 메소드로 실행할 메소드 이름을 전달하고 싶습니다.
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 코드를 작성하는 방법입니다.
답변
.net 3.5의 Func 델리게이트를 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 이것은 Func<T, TResult>
프레임 워크 의 일반 델리게이트 유형을 기반으로합니다 . 당신은 쉽게 자신을 선언 할 수 있습니다 :
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"));
답변
public static T Runner<T>(Func<T> funcToRun)
{
//Do stuff before running function as normal
return funcToRun();
}
용법:
var ReturnValue = Runner(() => GetUser(99));
답변
가능한 한 완전한 솔루션을 공유하기 위해 세 가지 다른 방법을 제시하지만 이제는 가장 기본적인 원칙부터 시작하겠습니다.
간단한 소개
C #, F # 및 Visual Basic과 같은 CLR ( 공용 언어 런타임 )에서 실행되는 모든 언어 는 VM에서 작동하며 C 및 C ++와 같은 기본 언어 (기계로 직접 컴파일)보다 높은 수준에서 코드를 실행합니다. 암호). 메소드는 어떤 종류의 컴파일 된 블록이 아니라 CLR이 인식하는 구조화 된 요소 일뿐입니다. 따라서 메소드는 표현식이 아니므로 자체적으로 값을 생성하지 않으므로 메소드를 매개 변수로 전달할 수 없습니다. 오히려 이들은 생성 된 CIL 코드에 정의 된 명령문입니다. 따라서 델리게이트 개념에 직면하게됩니다.
대리인은 무엇입니까?
델리게이트는 메소드에 대한 포인터를 나타냅니다. 위에서 말했듯이 메소드는 가치가 없으므로 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);
}
세 가지 다른 방법, 같은 개념 뒤에 :
-
방법 1 위의 예와 같이 특수 클래스를 직접
사용하십시오Delegate
. 이 솔루션의 문제는 인수를 메소드 정의의 인수 유형으로 제한하지 않고 인수를 동적으로 전달함에 따라 코드가 선택 해제된다는 것입니다. -
방법 2 특수 클래스
외에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"); }
-
방법 3
또는 .NET 표준 내에 이미 정의 된 대리자를 사용할 수도 있습니다.Action
void
인수없이 마무리합니다 .Action<T1>
void
하나의 인수로 마무리합니다 .Action<T1, T2>
void
두 개의 인수로 마무리합니다 .- 등등…
Func<TR>
TR
반환 유형과 인수가없는 함수를 마무리합니다 .Func<T1, TR>
TR
반환 유형과 하나의 인수 로 함수를 마무리합니다 .Func<T1, T2, TR>
TR
반환 유형과 두 개의 인수 로 함수를 마무리합니다 .- 등등…
후자의 솔루션은 대부분의 사람들이 게시 한 솔루션입니다.
답변
인수로 사용하고 :를 반환하는 Func<string, int>
함수를 나타내는 대리자를 사용해야 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);
}
답변
런타임에 호출되는 메소드를 변경하려면 위임을 사용하는 것이 좋습니다. http://www.codeproject.com/KB/cs/delegates_step1.aspx
호출 할 메소드를 저장할 오브젝트를 작성하고 필요할 때이를 다른 메소드에 전달할 수 있습니다.