programing tip

Func 란 무엇이며 언제 어떻게 사용합니까?

itbloger 2020. 8. 9. 10:11
반응형

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);

즉시 두 개의 다른 함수 ( )를 사용 하여 패턴을 나타내는 동일한 코드 (사용 )를 어떻게 활용할 수 있었는지 알 수 있습니다 .Selectp => p.Namep => 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:

  1. implement the interface

  2. 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

반응형