답변:
Func<T>
형식의 일부 값을 반환하는 메서드에 대해 미리 정의 된 대리자 형식입니다 T
.
즉,이 유형을 사용하여 일부 값을 반환하는 메서드를 참조 할 수 있습니다 T
. 예
public static string GetMessage() { return "Hello world"; }
다음과 같이 참조 될 수 있습니다.
Func<string> f = GetMessage;
Func<T>
입니다 delegate TResult Func<out TResult>()
. 인수가 없습니다. Func<T1, T2>
하나의 인수를 취하는 함수입니다.
static int OneArgFunc(this string i) { return 42; }
Func<int> f = "foo".OneArgFunc;
. =)
Extension
CLR이 아닌 C # / VB.Net 컴파일러에서만 읽는 속성입니다. 기본적으로 인스턴스 메서드 (정적 함수와 달리)에는 숨겨진 0 번째 "this"매개 변수가 있습니다. 따라서 1 인수 인스턴스 메소드는 2 인수 정적 함수와 매우 유사합니다. 그런 다음 대상 객체와 함수 포인터 를 저장하는 델리게이트가 있습니다 . 대리자는 첫 번째 인수를 target에 저장할 수 있거나 저장 하지 않을 수 있습니다.
자리 표시 자로 생각하십시오. 특정 패턴을 따르지만 특정 기능에 묶일 필요가없는 코드가있을 때 매우 유용 할 수 있습니다.
예를 들어 Enumerable.Select
확장 방법을 고려하십시오 .
이 방법은 Func<T, TResult>
구체적인 기능 대신을 사용합니다. 이를 통해 위의 패턴이 적용되는 모든 컨텍스트에서 사용할 수 있습니다 .
예를 들어, 내가 a가 List<Person>
있고 목록에있는 모든 사람의 이름 만 원한다고 가정합니다. 나는 이것을 할 수있다 :
var names = people.Select(p => p.Name);
또는 모든 사람 의 나이 를 원한다고 말합니다.
var ages = people.Select(p => p.Age);
즉시 두 개의 다른 함수 ( 및 )를 사용 하여 패턴을 나타내는 동일한 코드 (사용 )를 어떻게 활용할 수 있었는지 알 수 있습니다 .Select
p => p.Name
p => p.Age
대안은 Select
다른 종류의 값에 대해 시퀀스를 스캔하려고 할 때마다 다른 버전을 작성하는 것입니다. 따라서 위와 동일한 효과를 얻으려면 다음이 필요합니다.
// Presumably, the code inside these two methods would look almost identical;
// the only difference would be the part that actually selects a value
// based on a Person.
var names = GetPersonNames(people);
var ages = GetPersonAges(people);
대리자가 자리 표시 자 역할을하므로 이와 같은 경우 동일한 패턴을 반복해서 작성하지 않아도됩니다.
Func<T1, T2, ..., Tn, Tr>
(T1, T2, ..., Tn) 인수를 취하고 Tr을 반환하는 함수를 나타냅니다.
예를 들어 함수가있는 경우 :
double sqr(double x) { return x * x; }
일종의 함수 변수로 저장할 수 있습니다.
Func<double, double> f1 = sqr;
Func<double, double> f2 = x => x * x;
그런 다음 sqr을 사용하는 것과 똑같이 사용하십시오.
f1(2);
Console.WriteLine(f2(f1(4)));
기타
그러나 더 자세한 정보는 문서를 참조하십시오.
내가 찾을 Func<T>
내가 필요 "즉석에서"맞춤 수있는 구성 요소를 만들 때 매우 유용합니다.
이 아주 간단한 예를 들어 보자 : PrintListToConsole<T>
컴포넌트.
이 개체 목록을 콘솔에 인쇄하는 매우 간단한 개체입니다. 이를 사용하는 개발자가 출력을 개인화하도록하고 싶습니다.
예를 들어 특정 유형의 숫자 형식 등을 정의 할 수 있습니다.
Func없이
먼저 입력을 받아 콘솔에 인쇄 할 문자열을 생성하는 클래스 용 인터페이스를 만들어야합니다.
interface PrintListConsoleRender<T> {
String Render(T input);
}
그런 다음 PrintListToConsole<T>
이전에 만든 인터페이스를 가져 와서 목록의 각 요소에 사용 하는 클래스를 만들어야 합니다.
class PrintListToConsole<T> {
private PrintListConsoleRender<T> _renderer;
public void SetRenderer(PrintListConsoleRender<T> r) {
// this is the point where I can personalize the render mechanism
_renderer = r;
}
public void PrintToConsole(List<T> list) {
foreach (var item in list) {
Console.Write(_renderer.Render(item));
}
}
}
구성 요소를 사용해야하는 개발자는 다음을 수행해야합니다.
인터페이스 구현
실제 수업을 PrintListToConsole
class MyRenderer : PrintListConsoleRender<int> {
public String Render(int input) {
return "Number: " + input;
}
}
class Program {
static void Main(string[] args) {
var list = new List<int> { 1, 2, 3 };
var printer = new PrintListToConsole<int>();
printer.SetRenderer(new MyRenderer());
printer.PrintToConsole(list);
string result = Console.ReadLine();
}
}
Func를 사용하면 훨씬 간단합니다.
컴포넌트 내부에서 T 유형의 입력 매개 변수를 취하고 문자열 (콘솔의 출력)을 리턴하는 함수의 인터페이스Func<T,String>
를 나타내는 유형의 매개 변수를 정의합니다.
class PrintListToConsole<T> {
private Func<T, String> _renderFunc;
public void SetRenderFunc(Func<T, String> r) {
// this is the point where I can set the render mechanism
_renderFunc = r;
}
public void Print(List<T> list) {
foreach (var item in list) {
Console.Write(_renderFunc(item));
}
}
}
개발자가 구성 요소를 사용할 때 단순히 Func<T, String>
유형 의 구현 , 즉 콘솔에 대한 출력을 생성하는 함수를 구성 요소에 전달합니다 .
class Program {
static void Main(string[] args) {
var list = new List<int> { 1, 2, 3 }; // should be a list as the method signature expects
var printer = new PrintListToConsole<int>();
printer.SetRenderFunc((o) => "Number:" + o);
printer.Print(list);
string result = Console.ReadLine();
}
}
Func<T>
즉석에서 일반 메소드 인터페이스를 정의 할 수 있습니다.
입력 유형과 출력 유형을 정의합니다. 간단하고 간결합니다.
미리 정의 된 일반 대리자 일뿐입니다. 그것을 사용하면 모든 델리게이트를 선언 할 필요가 없습니다. Action<T, T2...>
동일하지만 void를 반환하는 또 다른 미리 정의 된 대리자가 있습니다 .
정보를 추가하기에 너무 늦지 않았을 수도 있습니다.
합집합:
Func는 시스템 네임 스페이스에 정의 된 사용자 지정 대리자로서 0 ~ 16 개의 입력 매개 변수를 사용하고 무언가를 반환해야하는 동일한 서명 (대리자처럼)을 가진 메서드를 가리킬 수 있습니다.
명명법 및 사용 방법 :
Func<input_1, input_2, ..., input1_6, output> funcDelegate = someMethod;
정의:
public delegate TResult Func<in T, out TResult>(T arg);
사용 장소 :
람다 식 및 익명 메서드에 사용됩니다.