ফানক কী, কখন এবং কখন এটি ব্যবহৃত হয়


115

এটি কী Func<>এবং এর জন্য ব্যবহৃত হয়?


4
এটি একটি নির্দিষ্ট স্বাক্ষরযুক্ত প্রতিনিধিদের জন্য কেবল একটি শর্টকাট। নীচের উত্তরগুলি পুরোপুরি বুঝতে আপনার প্রতিনিধিদের বুঝতে হবে ;-)
থিও লেনডরফ

2
@Oded এর উত্তরে এটা বলে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.
LCJ

উত্তর:


76

Func<T>কোনও পদ্ধতির জন্য পূর্বনির্ধারিত প্রতিনিধি প্রকার যা ধরণের কিছু মান দেয় T

অন্য কথায়, আপনি একটি পদ্ধতি যে কিছু মান রেফারেন্স এই ধরনের ব্যবহার করতে পারেন T। যেমন

public static string GetMessage() { return "Hello world"; }

এই মত উল্লেখ করা যেতে পারে

Func<string> f = GetMessage;

তবে এটি একটি স্থির ওয়ান-আর্গুমেন্ট ফাংশনকেও প্রতিনিধিত্ব করতে পারে =)
অর্ক-কুন

2
@ অর্ক-কুন, এটি সঠিক নয়। এর সংজ্ঞাটি Func<T>হ'ল delegate TResult Func<out TResult>()। কোন যুক্তি নেই। Func<T1, T2>একটি যুক্তি লাগে যে একটি ফাংশন হবে।
ব্রায়ান রাসমুসেন

4
না, আমি সঠিক। static int OneArgFunc(this string i) { return 42; } Func<int> f = "foo".OneArgFunc;। =)
অর্ক-কুন

1
এটি একটি এক্সটেনশন পদ্ধতি যা বিশেষ।
ব্রায়ান রাসমুসেন

এটি সম্পর্কে কেবলমাত্র বিশেষ জিনিসটি হ'ল Extensionবৈশিষ্ট্য যা কেবল সি # / ভিবি. নেট সংকলকগুলি পড়ে, না সিএলআর। মূলত, উদাহরণের পদ্ধতিগুলিতে (স্ট্যাটিক ফাংশনগুলির বিপরীতে) একটি "লুকানো" প্যারামিটার 0 টি লুকানো থাকে। সুতরাং, 1-আর্গুমেন্ট উদাহরণ পদ্ধতি 2-যুক্তি স্ট্যাটিক ফাংশনের সাথে খুব মিল। তারপরে, আমাদের প্রতিনিধিরা থাকে যা লক্ষ্য অবজেক্ট এবং ফাংশন পয়েন্টার সঞ্চয় করে । প্রতিনিধিরা প্রথম যুক্তিকে লক্ষ্যবস্তুতে সঞ্চয় করতে পারে বা এটি না করে।
অর্ক-কুন

87

এটিকে স্থানধারক হিসাবে ভাবেন। আপনার কাছে কোড রয়েছে যা নির্দিষ্ট প্যাটার্ন অনুসরণ করে তবে কোনও নির্দিষ্ট কার্যকারিতার সাথে আবদ্ধ হওয়ার প্রয়োজন নেই এটি কার্যকরভাবে কার্যকর হতে পারে।

উদাহরণস্বরূপ, Enumerable.Selectএক্সটেনশন পদ্ধতিটি বিবেচনা করুন ।

  • প্যাটার্ন হল: একটি ক্রমানুসারে প্রতিটি আইটেম, যে আইটেম (যেমন, একটি সম্পত্তি) থেকে কিছু মান নির্বাচন করুন এবং একটি নতুন এই মান নিয়ে গঠিত ক্রম তৈরি করুন।
  • স্থানধারক হল: কিছু নির্বাচক ফাংশন যে আসলে ক্রম মান পায় উপরে বর্ণিত।

এই পদ্ধতিটি Func<T, TResult>কোনও কংক্রিট ফাংশনের পরিবর্তে গ্রহণ করে। উপরের প্যাটার্নটি প্রয়োগ হয় এমন যে কোনও প্রসঙ্গে এটি এটি ব্যবহার করতে দেয় ।

সুতরাং উদাহরণস্বরূপ, বলুন আমার একটি আছে 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);

একজন প্রতিনিধি প্লেসহোল্ডারের চরিত্রে অভিনয় করে আমি এই জাতীয় ক্ষেত্রে বার বার একই ধরণটি লেখার হাত থেকে নিজেকে মুক্ত করি।


66

Func<T1, T2, ..., Tn, Tr> এমন একটি ফাংশন উপস্থাপন করে যা (টি 1, টি 2, ..., টিএন) আর্গুমেন্ট গ্রহণ করে এবং ট্রিকে প্রদান করে।

উদাহরণস্বরূপ, যদি আপনার কোনও ফাংশন থাকে:

double sqr(double x) { return x * x; }

আপনি এটিকে কোনও ধরণের ফাংশন-ভেরিয়েবল হিসাবে সংরক্ষণ করতে পারেন:

Func<double, double> f1 = sqr;
Func<double, double> f2 = x => x * x;

এবং তারপরে আপনি যেমন স্কয়ার ব্যবহার করবেন ঠিক তেমন ব্যবহার করুন:

f1(2);
Console.WriteLine(f2(f1(4)));

প্রভৃতি

মনে রাখবেন, এটি একটি প্রতিনিধি, আরও উন্নত তথ্যের জন্য ডকুমেন্টেশন পড়ুন।


1
দুর্দান্ত উত্তর, তবে মূলশব্দটি পূরণের জন্য স্থিতিশীল করা দরকার
বোকটুলাস

16

আমি খুঁজে 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));
        }
    }   
}

আপনার উপাদানটি ব্যবহার করতে হবে এমন বিকাশকারীদের এগুলি করতে হবে:

  1. ইন্টারফেস বাস্তবায়ন

  2. বাস্তব ক্লাস পাস 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>আপনাকে ফ্লাইতে একটি জেনেরিক পদ্ধতি ইন্টারফেসটি সংজ্ঞায়িত করতে দেয়। ইনপুটটি কোন প্রকার এবং আউটপুট কী প্রকার তা নির্ধারণ করে। সহজ এবং সংক্ষিপ্ত।


2
এই মার্কো পোস্ট করার জন্য ধন্যবাদ। এটা সত্যিই আমাকে সাহায্য করেছে। আমি কিছুক্ষণের জন্য ফানক বোঝার চেষ্টা করছি এবং এটি আমার প্রোগ্রামিংয়ে সক্রিয়ভাবে ব্যবহার করতে চাই। এই উদাহরণটি পথ পরিষ্কার করবে। মূল কোডে যেটি প্রদর্শন করা থেকে বিরত ছিল সে হিসাবে আমাকে স্ট্যাম্পাফঙ্ক পদ্ধতিটি যুক্ত করতে হয়েছিল।
সিওয়াকু অ্যাডোলা

1
আমি মনে করি ফানক নমুনায় একটি লাইন মিস হয়েছে, প্রিন্ট ফাংশন বা স্ট্যাম্পাফঙ্কের জন্য কলটি কোথায়?
বাশার আবু শামা

11

Func<T1,R>এবং অন্যান্য পূর্বনির্ধারিত জেনেরিক Funcপ্রতিনিধিদের ( Func<T1,T2,R>, Func<T1,T2,T3,R>এবং অন্যদের) জেনেরিক প্রতিনিধিদের যে গত জেনেরিক পরামিতি ধরণ আসতে হয়।

প্যারামিটারের উপর নির্ভর করে যদি আপনার কোনও ফাংশন থাকে যা বিভিন্ন ধরণের প্রত্যাবর্তনের প্রয়োজন হয়, আপনি Funcরিটার্নের ধরণ উল্লেখ করে একটি প্রতিনিধি ব্যবহার করতে পারেন ।


7

এটি কেবল একটি পূর্বনির্ধারিত জেনেরিক প্রতিনিধি। এটি ব্যবহার করে আপনার প্রত্যেক প্রতিনিধি ঘোষণা করার দরকার নেই। এখানে আরও একটি পূর্বনির্ধারিত প্রতিনিধি রয়েছে, Action<T, T2...>যা একই তবে অকার্যকর ফিরে আসে।


0

হয়তো কিছু তথ্য যোগ করতে দেরি হয়নি।

যোগফল:

ফানক হ'ল সিস্টেম নেমস্পেসে সংজ্ঞায়িত একটি কাস্টম প্রতিনিধি যা আপনাকে 0 থেকে 16 ইনপুট প্যারামিটার ব্যবহার করে একই স্বাক্ষরযুক্ত কোনও পদ্ধতিতে নির্দেশ করতে দেয় (প্রতিনিধিরা যেমন করে) এবং অবশ্যই কিছু ফেরত দিতে হবে।

নামকরণ এবং কীভাবে ব্যবহার:

Func<input_1, input_2, ..., input1_6, output> funcDelegate = someMethod;

সংজ্ঞা:

public delegate TResult Func<in T, out TResult>(T arg);

এটি কোথায় ব্যবহৃত হয়:

এটি ল্যাম্বদা এক্সপ্রেশন এবং বেনামে পদ্ধতিতে ব্যবহৃত হয়।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.