সি # তর্ক হিসাবে পাসিং ফাংশন


141

আমি সি # তে একটি ফাংশন লিখেছি যা সংখ্যার পার্থক্য করে। দেখে মনে হচ্ছে:

public double Diff(double x)
{
    double h = 0.0000001;

    return (Function(x + h) - Function(x)) / h;
}

আমি যে কোনও ফাংশনে পাস করতে সক্ষম হতে চাই:

public double Diff(double x, function f)
{
    double h = 0.0000001;

    return (f(x + h) - f(x)) / h;
}

আমি মনে করি প্রতিনিধিদের সাথে এটি সম্ভব (সম্ভবত?) তবে আমি কীভাবে সেগুলি ব্যবহার করব তা নিশ্চিত নই।

কোন সাহায্যের ব্যাপকভাবে প্রশংসা হবে।

উত্তর:


146

উপরে উল্লিখিত ফানকটি ব্যবহার করে যেমন কাজ করে তবে এমন প্রতিনিধিরাও থাকেন যা একই কাজটি করে এবং নামকরণের মধ্যে অভিপ্রায়ও সংজ্ঞায়িত করে:

public delegate double MyFunction(double x);

public double Diff(double x, MyFunction f)
{
    double h = 0.0000001;

    return (f(x + h) - f(x)) / h;
}

public double MyFunctionMethod(double x)
{
    // Can add more complicated logic here
    return x + 10;
}

public void Client()
{
    double result = Diff(1.234, x => x * 456.1234);
    double secondResult = Diff(2.345, MyFunctionMethod);
}

5
৩.৩ এবং তারপরে, ফানক <> গুলি এবং প্রতিনিধিরা বিনিময়যোগ্য এবং এর অর্থ হল বেনাম প্রতিনিধি এবং ল্যাম্বডাস (যা বেনামে প্রতিনিধিদের জন্য সিনট্যাকটিক চিনি) ব্যবহার করা যেতে পারে। সুতরাং আপনি প্যারামিটারটিকে ফানক <ডাবল, ডাবল> বা একটি ডেলিগেট হিসাবে নির্দিষ্ট করেছেন কিনা যা ডাবল লাগে এবং ডাবল ফেরত দেয় তা আসলেই গুরুত্বপূর্ণ নয়। একজন নামী প্রতিনিধি আপনাকে কেবলমাত্র আসল সুবিধা দেয় তা হল এক্সএমএল-ডক মন্তব্য যুক্ত করার ক্ষমতা; বর্ণনামূলক নামগুলি প্রকারের পরিবর্তে প্যারামিটার নামের মতো কার্যকর করা সহজ।
কিথস

3
আমি যুক্তি দিয়ে বলব যে পদ্ধতিটির প্রোটোটাইপটি এখনও কোডটিকে ফানক <x, y> এর চেয়ে বেশি পঠনযোগ্য করে তোলে - এটি কেবল নামকরণই কোডকে পাঠ্যযোগ্য করে তোলে এবং আপনি যেমন বলেন যে কোডটিতে ল্যাম্বডাস পাস করা থেকে বিরত রাখে না।
ইয়ান জনসন

কোড স্পষ্টতার জন্য যদি প্রতিনিধি প্রকারের নামকরণ এত গুরুত্বপূর্ণ হয়, আমি মনে করি বেশিরভাগ ক্ষেত্রে আমি একটি ইন্টারফেস এবং বাস্তবায়নের দিকে ঝুঁকছি।
কোয়ান্টিন-স্টারিন

@ কাস্টারিন এটি কেবল প্রতিনিধিদের নামকরণ নয়, পদ্ধতিটি অবশ্যই গ্রহণযোগ্য যুক্তিগুলির নামকরণ, বিশেষত যদি তারা কেবল দেশীয় প্রকারের হয়। আপনি ঠিক বলেছেন, বেশিরভাগ ক্ষেত্রে আমি প্রতিনিধিদের চেয়ে ইন্টারফেস ব্যবহার করি
ইয়ান জনসন

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

175

নেট (v2 এবং পরবর্তী) এর মধ্যে বেশ কয়েকটি জেনেরিক প্রকার রয়েছে যা প্রতিনিধি হিসাবে চারপাশে পাস করার কাজগুলি খুব সহজ করে তোলে।

রিটার্নের ধরণের ফাংশনগুলির জন্য, এখানে Func <> এবং ফিরতি প্রকারবিহীন ফাংশনগুলির জন্য অ্যাকশন <> রয়েছে।

ফানক এবং অ্যাকশন উভয়কেই 0 থেকে 4 পরামিতি পর্যন্ত গ্রহণের জন্য ঘোষণা করা যেতে পারে। উদাহরণস্বরূপ, ফানক <ডাবল, ইন্ট> প্যারামিটার হিসাবে এক ডাবল নেয় এবং একটি ইনট প্রদান করে। অ্যাকশন <ডাবল, ডাবল, ডাবল> পরামিতি হিসাবে তিনটি ডাবল লাগে এবং কিছুই (শূন্য) দেয় না।

সুতরাং আপনি একটি Func নিতে আপনার ডিফ ফাংশন ঘোষণা করতে পারেন:

public double Diff(double x, Func<double, double> f) {
    double h = 0.0000001;

    return (f(x + h) - f(x)) / h;
}

এবং তারপরে আপনি এটিকে এটি হিসাবে ডাকেন, কেবল এটিকে ফাংশনটির নাম দিন যা আপনার ফানক বা ক্রিয়াটির স্বাক্ষরের সাথে খাপ খায়:

double result = Diff(myValue, Function);

এমনকি ল্যাম্বদা সিনট্যাক্স সহ ফাংশনটি ইন-লাইনে লিখতে পারেন:

double result = Diff(myValue, d => Math.Sqrt(d * 3.14));

29
.NET 4 এ, উভয়ই Funcএবং 16 টি পরামিতি পর্যন্তAction অনুমতি দেওয়ার জন্য আপডেট করা হয়েছে ।
জোয়েল মুলার 21

5
সত্যিই শীতল জিনিসটি Func<double, double>হ'ল এটিই ফিরিয়ে দেওয়া হবে যা অবশ্যই ইনপুট ফাংশনের প্রথম ডেরাইভেটিভ, সংখ্যাগতভাবে গণনা করা। return x => (f(x + h) - f(x)) / h;এমনকি আপনি একটি ওভারলোডও লিখতে পারেন nযা ইনপুট ফাংশনটির ডেরিভেটিভ ফিরিয়ে দেয় ।
আনি

15
public static T Runner<T>(Func<T> funcToRun)
{
    //Do stuff before running function as normal
    return funcToRun();
}

ব্যবহার:

var ReturnValue = Runner(() => GetUser(99));

আমি কৌতূহলী, জেনেরিক টাইপ প্যারামিটার কেন?
kdbanman

2
আমি এই ত্রুটিটি পাচ্ছি: পদ্ধতির জন্য 'রানার <T> (ফানক <টি>)' জাতীয় ধরণের আর্গুমেন্টগুলি ব্যবহার থেকে অনুমান করা যায় না। প্রকারের আর্গুমেন্টগুলি স্পষ্ট করে উল্লেখ করার চেষ্টা করুন।
ডার্মফ্রান্স

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