Func 란 무엇이며 언제 어떻게 사용합니까?
무엇 Func<>
이며 무엇을 위해 사용됩니까?
Func<T>
형식의 일부 값을 반환하는 메서드에 대해 미리 정의 된 대리자 형식입니다 T
.
즉,이 유형을 사용하여 일부 값을 반환하는 메서드를 참조 할 수 있습니다 T
. 예
public static string GetMessage() { return "Hello world"; }
다음과 같이 참조 될 수 있습니다.
Func<string> f = GetMessage;
자리 표시 자로 생각하십시오. 특정 패턴을 따르지만 특정 기능에 묶일 필요가없는 코드가있을 때 매우 유용 할 수 있습니다.
예를 들어 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<T1,R>
다른 미리 정의 된 제네릭 Func
대표 ( Func<T1,T2,R>
, Func<T1,T2,T3,R>
등)은 최종 제네릭 매개 변수의 형식을 반환 일반적인 대표입니다.
매개 변수에 따라 다른 형식을 반환해야하는 함수가있는 경우 Func
반환 형식을 지정 하는 대리자를 사용할 수 있습니다 .
내가 찾을 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));
}
}
}
The developer that needs to use your component has to:
implement the interface
pass the real class to the
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(); } }
Using Func it's much simpler
Inside the component you define a parameter of type Func<T,String>
that represents an interface of a function that takes an input parameter of type T and returns a string (the output for the console)
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));
}
}
}
When the developer uses your component he simply passes to the component the implementation of the Func<T, String>
type, that is a function that creates the output for the console.
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>
lets you define a generic method interface on the fly. You define what type the input is and what type the output is. Simple and concise.
It is just a predefined generic delegate. Using it you don't need to declare every delegate. There is another predefined delegate, Action<T, T2...>
, which is the same but returns void.
Maybe it is not too late to add some info.
Sum:
The Func is a custom delegate defined in System namespace that allows you to point to a method with the same signature (as delegates do), using 0 to 16 input parameters and that must return something.
Nomenclature & how2use:
Func<input_1, input_2, ..., input1_6, output> funcDelegate = someMethod;
Definition:
public delegate TResult Func<in T, out TResult>(T arg);
Where it is used:
It is used in lambda expressions and anonymous methods.
참고URL : https://stackoverflow.com/questions/3624731/what-is-func-how-and-when-is-it-used
'programing tip' 카테고리의 다른 글
인스턴스간에 내 Visual Studio Code 설정을 동기화하는 방법이 있습니까? (0) | 2020.08.10 |
---|---|
불변 클래스는 어떻게 만듭니 까? (0) | 2020.08.10 |
Scala : 배열에 요소를 추가하는 가장 좋은 방법은 무엇입니까? (0) | 2020.08.09 |
부모 컨테이너와 관련된 요소의 위치 / 오프셋을 얻습니까? (0) | 2020.08.09 |
model.save ()에서 성공 콜백을 어떻게 트리거합니까? (0) | 2020.08.09 |