क्या है Func<>
और इसका उपयोग किस लिए किया जाता है?
If you have a function that needs to return different types, depending on the parameters, you can use a Func delegate, specifying the return type.
क्या है Func<>
और इसका उपयोग किस लिए किया जाता है?
If you have a function that needs to return different types, depending on the parameters, you can use a Func delegate, specifying the return type.
जवाबों:
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
विशेषता है जो केवल C # / VB.Net संकलक द्वारा पढ़ा जाता है, सीएलआर नहीं। मूल रूप से, उदाहरण के तरीकों (स्थिर कार्यों के विपरीत) में एक छिपा हुआ 0 वां "यह" पैरामीटर है। तो, 1-तर्क उदाहरण विधि 2-तर्क स्थिर फ़ंक्शन के समान है। फिर, हमारे पास प्रतिनिधि हैं जो लक्ष्य ऑब्जेक्ट और फ़ंक्शन पॉइंटर को स्टोर करते हैं । प्रतिनिधि लक्ष्य में पहला तर्क संग्रहीत कर सकते हैं या नहीं।
इसे एक प्लेसहोल्डर के रूप में सोचें। यह काफी उपयोगी हो सकता है जब आपके पास एक निश्चित पैटर्न का अनुसरण करने वाला कोड हो, लेकिन उसे किसी विशेष कार्यक्षमता से न जोड़ा जाए।
उदाहरण के लिए, Enumerable.Select
विस्तार विधि पर विचार करें ।
यह विधि Func<T, TResult>
किसी भी ठोस कार्य के बजाय लेती है । यह इसे किसी भी संदर्भ में उपयोग करने की अनुमति देता है जहां उपरोक्त पैटर्न लागू होता है।
उदाहरण के लिए, मान लीजिए कि मेरे पास 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>
घटक।
एक बहुत ही सरल वस्तु जो वस्तुओं की इस सूची को कंसोल पर प्रिंट करती है। आप डेवलपर को इसका उपयोग करने देना चाहते हैं जो आउटपुट को निजीकृत करता है।
उदाहरण के लिए, आप उसे एक विशेष प्रकार के संख्या प्रारूप आदि को परिभाषित करने देना चाहते हैं।
फंक के बिना
सबसे पहले, आपको एक वर्ग के लिए एक इंटरफ़ेस बनाना होगा जो इनपुट लेता है और कंसोल को प्रिंट करने के लिए स्ट्रिंग पैदा करता है।
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,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>
आपको मक्खी पर एक सामान्य विधि इंटरफ़ेस को परिभाषित करने देता है।
आप परिभाषित करते हैं कि इनपुट किस प्रकार का है और आउटपुट किस प्रकार का है। सरल और संक्षिप्त।
Func<T1,R>
और अन्य पूर्वनिर्धारित सामान्य Func
प्रतिनिधियों ( Func<T1,T2,R>
, Func<T1,T2,T3,R>
और अन्य) सामान्य प्रतिनिधियों कि पिछले सामान्य पैरामीटर के प्रकार वापसी कर रहे हैं।
यदि आपके पास एक फ़ंक्शन है जो विभिन्न प्रकारों को वापस करने की आवश्यकता है, तो मापदंडों के आधार पर, आप ए का उपयोग कर सकते हैं Func
प्रतिनिधि का , रिटर्न प्रकार निर्दिष्ट ।
यह सिर्फ एक पूर्वनिर्धारित जेनेरिक प्रतिनिधि है। इसका उपयोग करते हुए आपको प्रत्येक प्रतिनिधि को घोषित करने की आवश्यकता नहीं है। एक और पूर्वनिर्धारित प्रतिनिधि है, Action<T, T2...>
जो एक ही है, लेकिन रिटर्न शून्य है।
शायद कुछ जानकारी जोड़ने में देर नहीं हुई है।
सम:
फंक सिस्टम नामस्थान में परिभाषित एक कस्टम प्रतिनिधि है जो आपको 0 से 16 इनपुट मापदंडों का उपयोग करके एक ही हस्ताक्षर (जैसा कि प्रतिनिधि करते हैं) के साथ एक विधि को इंगित करने की अनुमति देता है और उसे कुछ वापस करना होगा।
नामकरण और how2use:
Func<input_1, input_2, ..., input1_6, output> funcDelegate = someMethod;
परिभाषा:
public delegate TResult Func<in T, out TResult>(T arg);
इसका उपयोग कहां किया जाता है:
इसका उपयोग लंबोदर भाव और अनाम विधियों में किया जाता है।