স্থানীয় ফাংশন বনাম ল্যাম্বদা সি # 7.0


178

আমি সি # 7.0 এ নতুন বাস্তবায়নের দিকে নজর দিচ্ছি এবং আমি এটি আকর্ষণীয় মনে করি যে তারা স্থানীয় ফাংশনগুলি বাস্তবায়িত করেছে তবে আমি এমন একটি দৃশ্য কল্পনা করতে পারি না যেখানে কোনও ল্যাম্বডা এক্সপ্রেশনের চেয়ে স্থানীয় ফাংশনকেই প্রাধান্য দেওয়া হবে এবং দুটির মধ্যে পার্থক্য কী।

আমি বুঝতে পারি যে ল্যাম্বডাস হ'ল anonymousফাংশন এদিকে স্থানীয় ফাংশনগুলি না, তবে আমি একটি বাস্তব বিশ্বের দৃশ্যধারণ করতে পারি না, যেখানে ল্যাম্বডা এক্সপ্রেশনগুলির তুলনায় স্থানীয় ফাংশনটির সুবিধা রয়েছে

কোন উদাহরণ অনেক প্রশংসা হবে। ধন্যবাদ।


9
জেনারিক্স, আউট প্যারামিটারগুলি, ল্যাম্বডাকে শূন্য করা শুরু করা ছাড়া পুনরাবৃত্ত ক্রিয়াকলাপগুলি
কার্ক ওল

5
@ কির্কওয়োল - আপনার উত্তর হিসাবে এটি পোস্ট করা উচিত।
Enigmativity

উত্তর:


276

এটি সি # ডিজাইন মিটিং নোটগুলিতে ম্যাডস টর্গারসেন দ্বারা ব্যাখ্যা করা হয়েছিল যেখানে স্থানীয় ফাংশনগুলি প্রথমে আলোচনা করা হয়েছিল :

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

এটিতে আরও কিছু প্রসারিত করার জন্য সুবিধাগুলি হ'ল:

  1. কর্মক্ষমতা.

    ল্যাম্বদা তৈরি করার সময়, একটি প্রতিনিধি তৈরি করতে হবে, যা এই ক্ষেত্রে একটি অপ্রয়োজনীয় বরাদ্দ। স্থানীয় ফাংশনগুলি সত্যই কেবল ফাংশন, কোনও প্রতিনিধি প্রয়োজন হয় না।

    এছাড়াও স্থানীয় ফাংশনগুলি স্থানীয় ভেরিয়েবলগুলি ক্যাপচারের সাথে আরও দক্ষ: ল্যাম্বডাস সাধারণত একটি শ্রেণিতে ভেরিয়েবলগুলি ক্যাপচার করে, স্থানীয় ফাংশনগুলি স্ট্রাক্ট ব্যবহার করে (পাস করে ref) ব্যবহার করতে পারে , যা আবার বরাদ্দ এড়ানো হয়।

    এর অর্থ হ'ল স্থানীয় ফাংশনগুলিকে কল করা সস্তা এবং এগুলি অন্তর্ভুক্ত করা যেতে পারে, সম্ভবত আরও কার্য সম্পাদন আরও বাড়ানো।

  2. স্থানীয় ফাংশন পুনরাবৃত্তি হতে পারে।

    লাম্বদাসও পুনরাবৃত্তিযোগ্য হতে পারে তবে এর জন্য বিশ্রী কোড দরকার, যেখানে আপনি প্রথমে nullএকটি প্রতিনিধি ভেরিয়েবল এবং তার পরে ল্যাম্বডাকে অর্পণ করেন। স্থানীয় ফাংশনগুলি প্রাকৃতিকভাবে পুনরাবৃত্ত হতে পারে (পারস্পরিক পুনরাবৃত্তি সহ)।

  3. স্থানীয় ফাংশন জেনেরিক হতে পারে।

    ল্যাম্বডাস জেনেরিক হতে পারে না, যেহেতু তাদেরকে একটি কংক্রিট টাইপের সাথে একটি ভেরিয়েবলের নিয়োগ করতে হবে (এই ধরণেরটি বাহ্যিক ক্ষেত্র থেকে জেনেরিক ভেরিয়েবল ব্যবহার করতে পারে, তবে এটি একই জিনিস নয়)।

  4. স্থানীয় ফাংশন একটি পুনরাবৃত্তকারী হিসাবে প্রয়োগ করা যেতে পারে।

    ল্যাম্বডাস পুনরায় তৈরির ফাংশনটি প্রয়োগ করতে yield return(এবং yield break) কীওয়ার্ডটি ব্যবহার করতে পারে না IEnumerable<T>। স্থানীয় ফাংশন পারেন।

  5. স্থানীয় ফাংশনগুলি আরও ভাল দেখায়।

    উপরের উদ্ধৃতিতে এটি উল্লেখ করা হয়নি এবং এটি কেবল আমার ব্যক্তিগত পক্ষপাতিত্ব হতে পারে তবে আমি মনে করি যে কোনও ফ্যামিলিটি ভেরিয়েবলের কাছে ল্যাম্বডা নির্ধারণের চেয়ে স্বাভাবিক ফাংশন সিনট্যাক্সটি আরও ভাল দেখাচ্ছে। স্থানীয় ফাংশনগুলি আরও সংক্ষিপ্ত।

    তুলনা করা:

    int add(int x, int y) => x + y;
    Func<int, int, int> add = (x, y) => x + y;

22
আমি যুক্ত করতে চাই যে স্থানীয় ফাংশনগুলির কলার দিকে প্যারামিটারের নাম রয়েছে। লাম্বদা না।
লেন্সফ্লেয়ার

3
@ লেন্সফ্লেয়ার এটি সত্য যে ল্যাম্বডাসের প্যারামিটারের নামগুলি সংরক্ষণ করা হয়নি, তবে এটি কারণ তাদের প্রতিনিধিদের রূপান্তর করতে হবে, যার নিজস্ব নাম রয়েছে। উদাহরণস্বরূপ: Func<int, int, int> f = (x, y) => x + y; f(arg1:1, arg2:1);
এসভিিক

1
দুর্দান্ত তালিকা! যাইহোক, আমি কল্পনা করতে পারি যে আইএল / জেআইটি সংকলক ১.-তে উল্লিখিত সমস্ত অপ্টিমাইজেশানগুলি কীভাবে সম্পাদন করতে পারে যদি এছাড়াও প্রতিনিধিদের জন্য যদি তাদের ব্যবহার নির্দিষ্ট বিধি মেনে চলে।
মার্সিন কাকজমেরেক

1
@ ক্যাসাব্যাশ কারণ ল্যাম্বডাস সর্বদা একটি প্রতিনিধি ব্যবহার করে এবং সেই প্রতিনিধি ক্লোজটিকে একটি হিসাবে ধরে রাখে object। সুতরাং, ল্যাম্বডাস একটি কাঠামো ব্যবহার করতে পারে তবে এটি বাক্সে রাখতে হবে, তাই আপনার এখনও অতিরিক্ত অতিরিক্ত বরাদ্দ থাকবে।
সুইভ

1
@ হ্যাপিবিটস বেশিরভাগ ক্ষেত্রে যখন আপনার কোনও নাম দেওয়ার দরকার নেই, যেমন আপনি যখন পদ্ধতিতে পাস করছেন তখন।
সোভিক

83

এসভিকের দুর্দান্ত উত্তরের পাশাপাশি স্থানীয় ফাংশনগুলির আরও একটি সুবিধা রয়েছে:
এগুলি returnবিবৃতি দেওয়ার পরেও ফাংশনটিতে যে কোনও জায়গায় সংজ্ঞায়িত করা যায় ।

public double DoMath(double a, double b)
{
    var resultA = f(a);
    var resultB = f(b);
    return resultA + resultB;

    double f(double x) => 5 * x + 3;
}

5
এটি সত্যিই দরকারী, যেহেতু আমি ফাংশনটির #region Helpersনীচে সমস্ত সহায়ক ফাংশনগুলি রাখার অভ্যস্ত হয়ে উঠতে পারি, সুতরাং সেই ফাংশনের মধ্যে বিশৃঙ্খলা এড়াতে এবং স্পষ্টতই মূল শ্রেণীর মধ্যে বিশৃঙ্খলা এড়াতে।
অস্টিন ডাব্লু ব্রায়ান

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

3
যদি আপনার ফাংশনগুলি এত বড় হয় তবে সেগুলির মধ্যে অঞ্চলগুলির প্রয়োজন, সেগুলি খুব বড়।
স্মিথ

9

আপনি যদি স্থানীয় ফাংশন কীভাবে পরীক্ষা করতে চান তাও যদি আপনি আশ্চর্য হন তবে আপনার জাস্টমককে পরীক্ষা করা উচিত কারণ এটির কার্যকারিতা রয়েছে। এখানে পরীক্ষা করা হবে এমন একটি সাধারণ শ্রেণির উদাহরণ:

public class Foo // the class under test
{ 
    public int GetResult() 
    { 
        return 100 + GetLocal(); 
        int GetLocal () 
        { 
            return 42; 
        } 
    } 
}

এবং এখানে পরীক্ষাটি কেমন দেখাচ্ছে:

[TestClass] 
public class MockLocalFunctions 
{ 
    [TestMethod] 
    public void BasicUsage() 
    { 
        //Arrange 
        var foo = Mock.Create<Foo>(Behavior.CallOriginal); 
        Mock.Local.Function.Arrange<int>(foo, "GetResult", "GetLocal").DoNothing(); 

        //Act 
        var result = foo. GetResult(); 

        //Assert 
        Assert.AreEqual(100, result); 
    } 
} 

এখানে জাস্টমক ডকুমেন্টেশনের লিঙ্ক ।

দাবি পরিত্যাগী। আমি জাস্টমকের জন্য দায়বদ্ধ অন্যতম বিকাশকারী ।


এই জাতীয় উত্সাহী বিকাশকারীরা লোকদের তাদের সরঞ্জাম ব্যবহার করার জন্য পরামর্শ দিচ্ছে তা দুর্দান্ত। আপনি কীভাবে একটি পূর্ণকালীন চাকরি হিসাবে বিকাশকারী সরঞ্জামগুলি লেখার বিষয়ে আগ্রহী হন? আমেরিকান হিসাবে, আমার ধারণাটি হ'ল যদি আপনার কোনও মাস্টার বা পিএইচডি না থাকে তবে এই জাতীয় ক্যারিয়ার সন্ধান করা কঠিন can কমপ্লেষে
জন জাব্রোস্কি

হাই জন এবং এই ধরনের শব্দগুলির জন্য আপনাকে ধন্যবাদ। সফ্টওয়্যার বিকাশকারী হিসাবে, আমি আমার ক্লায়েন্টদের যে মূল্য দিয়েছি তার জন্য প্রশংসা করার চেয়ে ভাল আর কিছুই আমি দেখতে পাচ্ছি না। চ্যালেঞ্জিং এবং প্রতিযোগিতামূলক কাজের জন্য আকাঙ্ক্ষার সাথে মিশ্রিত করুন এবং আপনি যে বিষয়ে আগ্রহী সেগুলির একটি মোটামুটি সীমিত তালিকা পাবেন। উত্পাদনশীলতা বিকাশকারী সরঞ্জাম লেখার তালিকায় রয়েছে ing কমপক্ষে আমার মনে :) ক্যারিয়ার সম্পর্কে, আমি মনে করি যে বিকাশকারী সরঞ্জাম সরবরাহকারী সংস্থাগুলি সমস্ত সফ্টওয়্যার সংস্থাগুলির মধ্যে একটি খুব সামান্য শতাংশ এবং এ কারণেই এই জাতীয় সুযোগ খুঁজে পাওয়া আরও কঠিন।
মিহাইল ভ্লাদভ

একটি পৃথক প্রশ্ন। আপনি এখানে কেন ভেরিফিল কল করবেন না? স্থানীয় ফাংশনটিও যাচাই করার জন্য জাস্টমককে বলার উপায় আছে কি?
জন জাব্রোস্কি

2
হাই @ জনজাব্রোস্কি, পরীক্ষিত দৃশ্যের জন্য দৃting়তার উপস্থিতিগুলির প্রয়োজন নেই। অবশ্যই, আপনি যাচাই করতে পারেন যে কোনও কল হয়েছিল। প্রথমত, আপনাকে পদ্ধতিটি কল করার জন্য কতবার আশা করতে হবে তা নির্দিষ্ট করতে হবে। .DoNothing().OccursOnce();এটির মতো: এবং পরে দাবি করুন যে Mock.Assert(foo);পদ্ধতিটি কল করে কল করা হয়েছিল । আপনি যদি আগ্রহী হন যে কীভাবে অন্যান্য পরিস্থিতিতে সমর্থন করা যায় আপনি আমাদের দৃ Occ়তা ঘটনার সহায়তা নিবন্ধটি পড়তে পারেন।
মিহাইল ভ্লাদভ

0

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

একটি যা করে তা হ'ল সার্ভারের সাথে সকেট সংযোগ খোলা এবং কোনও ইভেন্টকে ইভেন্টের সাথে আবদ্ধ করা ডেটা লুপ করে। ক্লাস ডিজাইনের মতো একইভাবে এটি ভাবতে পারে, কেবলমাত্র একজন পুরো জায়গা জুড়ে সহায়ক পদ্ধতি লিখছেন না যা কেবলমাত্র এক পিসের কার্যকারিতার জন্য কাজ করছে। এটি দেখতে কেমন হতে পারে তার কয়েকটি নমুনা নীচে দেওয়া হয়েছে, দয়া করে নোট করুন যে আমি ভেরিয়েবলগুলি ব্যবহার করছি এবং "সহায়ক" পদ্ধতিগুলি শেষ পর্যন্ত নীচে। পরিশেষে আমি ইভেন্ট হ্যান্ডলারগুলিকে খুব সুন্দরভাবে সরিয়ে দিই, যদি আমার এক্সচেঞ্জের ক্লাসটি বাহ্যিক / ইনজেকশনের হয়ে থাকে তবে আমার কোনও মুলতুবি ইভেন্ট হ্যান্ডলার নিবন্ধিত হবে না

void List<HistoricalData> RequestData(Ticker ticker, TimeSpan timeout)
{
    var socket= new Exchange(ticker);
    bool done=false;
    socket.OnData += _onData;
    socket.OnDone += _onDone;
    var request= NextRequestNr();
    var result = new List<HistoricalData>();
    var start= DateTime.Now;
    socket.RequestHistoricalData(requestId:request:days:1);
    try
    {
      while(!done)
      {   //stop when take to long….
        if((DateTime.Now-start)>timeout)
           break;
      }
      return result;

    }finally
    {
        socket.OnData-=_onData;
        socket.OnDone-= _onDone;
    }


   void _OnData(object sender, HistoricalData data)
   {
       _result.Add(data);
   }
   void _onDone(object sender, EndEventArgs args)
   {
      if(args.ReqId==request )
         done=true;
   } 
}

নীচে উল্লিখিত হিসাবে আপনি সুবিধাগুলি দেখতে পারেন, এখানে আপনি একটি নমুনা বাস্তবায়ন দেখতে পারেন। আশা করি এটি সুবিধাগুলি ব্যাখ্যা করতে সহায়তা করে।


2
১. এটি কেবল স্থানীয় ক্রিয়াকলাপ প্রদর্শনের জন্য এটি একটি জটিল উদাহরণ এবং ব্যাখ্যা। ২. উদাহরণস্বরূপ ল্যাম্বডাসের সাথে তুলনা করার সময় স্থানীয় ফাংশনগুলি কোনও বরাদ্দ এড়ায় না কারণ তাদের এখনও প্রতিনিধিতে রূপান্তর করতে হবে। সুতরাং তারা কীভাবে জিসি এড়িয়ে চলবে তা আমি দেখছি না।
এসভিউক

1
চারপাশে ভেরিয়েবলগুলি পাস / অনুলিপি না করা, এসভিকের উত্তর বাকীটি সত্যিই ভালভাবে কভার করে। তার উত্তর সদৃশ করার দরকার নেই
ওয়াল্টার Vehoeven
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.