প্রতিনিধি কীওয়ার্ড বনাম ল্যাম্বদা স্বরলিপি


184

এটি একবার সংকলিত হয়ে গেলে, এর মধ্যে কি পার্থক্য রয়েছে:

delegate { x = 0; }

এবং

() => { x = 0 }

?

উত্তর:


140

সংক্ষিপ্ত উত্তর: না।

দীর্ঘ উত্তর যা প্রাসঙ্গিক নাও হতে পারে:

  • আপনি যদি কোনও ল্যাম্বডাকে কোনও প্রতিনিধি প্রকারের জন্য নির্ধারণ করেন (যেমন Funcবা Action) আপনি একটি বেনাম প্রতিনিধি পাবেন।
  • যদি আপনি ল্যাম্বডাকে কোনও এক্সপ্রেশন টাইপের জন্য বরাদ্দ করেন তবে আপনি বেনামে প্রতিনিধি পরিবর্তে একটি এক্সপ্রেশন ট্রি পাবেন। এক্সপ্রেশন ট্রিটি তখন একটি অনামী প্রতিনিধিতে সংকলিত হতে পারে।

সম্পাদনা করুন: এক্সপ্রেশনগুলির জন্য এখানে কিছু লিঙ্ক রয়েছে।

  • System.Linq.Expression.Expression (TDelegate) (এখানে শুরু করুন)।
  • প্রতিনিধিদের সাথে লিনক ইন-মেমরি (যেমন System.Func) System.Linq.Eeumerable ব্যবহার করে । লিনাক থেকে এসকিউএল (এবং অন্য যে কোনও কিছু) এক্সপ্রেশন সহ System.Linq.Queryable ব্যবহার করে । এই পদ্ধতিগুলিতে পরামিতিগুলি পরীক্ষা করে দেখুন।
  • স্কটগু থেকে একটি ব্যাখ্যা । সংক্ষেপে, লিনক ইন-মেমরি আপনার প্রশ্নের সমাধানের জন্য কিছু বেনামী পদ্ধতি তৈরি করবে। লিনক থেকে এসকিউএল একটি এক্সপ্রেশন ট্রি তৈরি করবে যা ক্যোয়ারিকে উপস্থাপন করে এবং সেই গাছটিকে টি-এসকিউএলে অনুবাদ করবে। লিঙ্ক টু সত্তা একটি অভিব্যক্তি গাছ উত্পাদন করবে যা ক্যোয়ারিকে উপস্থাপন করে এবং সেই গাছটিকে প্ল্যাটফর্মের উপযুক্ত এসকিউএলে অনুবাদ করবে।

3
একটি এক্সপ্রেশন ধরনের? এটি আমার কাছে নতুন অঞ্চল বলে মনে হচ্ছে। সি # তে এক্সপ্রেশনের ধরণ এবং এক্সপ্রেশন ট্রি সম্পর্কে আরও কোথায় জানতে পারি?
মোজোফিল্টার

2
আরও দীর্ঘ উত্তর - তারা বিভিন্ন প্রতিনিধি ধরণের রূপান্তরিত হওয়ার জন্য খুব স্পষ্ট কারণ রয়েছে :)
জন স্কিটি

নোট করুন যে ল্যাম্বদা কেবল এক্সপ্রেশন টাইপের জন্য বরাদ্দ করা যেতে পারে, যদি এটি এক্সপ্রেশন লাম্বদা হয়।
মিশা উইডেনম্যান

125

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

তবে দুর্যোগের ধর্মঘট! কমপক্ষে সি # 3.0 এর সাহায্যে, আপনি ব্লক বডি সহ ল্যাম্বডা এক্সপ্রেশনটিকে একটি অভিব্যক্তিতে রূপান্তর করতে পারবেন না - বা আপনি কোনও ল্যাম্বডা এক্সপ্রেশনকে শরীরে কোনও অ্যাসাইনমেন্টের সাথে রূপান্তর করতে পারবেন না (এমনকি এটি ফেরতের মান হিসাবে ব্যবহৃত হলেও)। এটি সি # 4.0 এবং .NET 4.0 এর সাহায্যে পরিবর্তিত হতে পারে, যা এক্সপ্রেশন ট্রিতে আরও প্রকাশ করার অনুমতি দেয়। সুতরাং অন্য কথায়, মোজো ফিল্টার যে উদাহরণগুলি দিয়েছিল তা দিয়ে দু'জনেই প্রায় সবসময় একই জিনিসতে রূপান্তরিত হবে। (এক মিনিটের মধ্যে আরও বিশদ))

আমরা কিছুটা হলেও মৃতদেহগুলি পরিবর্তন করলে আমরা প্রতিনিধি পরামিতি কৌশলটি ব্যবহার করতে পারি:

using System;
using System.Linq.Expressions;

public class Test
{
    static void Main()
    {
        int x = 0;
        Foo( () => x );
        Foo( delegate { return x; } );
    }

    static void Foo(Func<int, int> action)
    {
        Console.WriteLine("I suspect the anonymous method...");
    }

    static void Foo(Expression<Func<int>> func)
    {
        Console.WriteLine("I suspect the lambda expression...");
    }
}

কিন্তু অপেক্ষা করো! আমরা যথেষ্ট চালাক হলে, আমরা অভিব্যক্তি গাছ ব্যবহার না করেও দুজনের মধ্যে পার্থক্য করতে পারি। নীচের উদাহরণটিতে ওভারলোড রেজোলিউশন বিধিগুলি (এবং বেনামে প্রতিনিধি মিলে যাওয়ার কৌশল) ব্যবহার করা হয়েছে ...

using System;
using System.Linq.Expressions;

public class Base
{
    public void Foo(Action action)
    {
        Console.WriteLine("I suspect the lambda expression...");
    }
}

public class Derived : Base
{
    public void Foo(Action<int> action)
    {
        Console.WriteLine("I suspect the anonymous method...");
    }
}

class Test
{
    static void Main()
    {
        Derived d = new Derived();
        int x = 0;
        d.Foo( () => { x = 0; } );
        d.Foo( delegate { x = 0; } );
    }
}

সেকি। বাচ্চাদের মনে রাখবেন, আপনি যখনই বেস ক্লাস থেকে উত্তরাধিকার সূত্রে কোনও পদ্ধতি ওভারলোড করেন, তখন একটি ছোট্ট বিড়ালছানা কাঁদতে শুরু করে।


9
আমি আমার পপকর্নটি বের করে পুরো জিনিসটি পড়েছি। এটি এমন কিছু পার্থক্য যা আমি মুখের মধ্যে সরাসরি স্টার করে দিলেও আমি কখনও ভাবতে পারি না।
মোজো ফিল্টার

27
আমি এর কয়েকটি জানতাম, তবে এটি অবশ্যই মানুষের কাছে জানাতে আপনার দক্ষতার জন্য আপনাকে অভিনন্দন জানাতে হবে।
অ্যামি বি

1
নেট নেট in.০ ( সিটিপির উপর ভিত্তি করে) পরিবর্তনে আগ্রহী যে কারও জন্য - marcgravell.blogspot.com/2008/11/future-expressions.html দেখুন । মনে রাখবেন যে সি # 4.0 যতদূর আমি বলতে পারি নতুন কিছু করে না।
মার্ক গ্র্যাভেল

4
জোন, আপনি দোলা। এরিক, সত্যিকারের স্কিট ফ্যানবোই হওয়ার জন্য, আপনার মতো তাঁর স্ট্যাক ওভারফ্লো আরএসএসের সাবস্ক্রাইব করা উচিত। আপনার ফিড রিডারটিতে কেবল স্ট্যাকওভারফ্লো.com/users/22656 লাগিয়ে দিন
পল বাতুম

3
@ রইনিমির: আপনি যদি কোনও প্যারামিটার তালিকা ছাড়াই বেনাম পদ্ধতি ব্যবহার করেন তবে এটি কোনও প্রতিনিধি প্রকারের সাথে রেফারেন্স / আউট প্যারামিটারের সাথে সামঞ্জস্যপূর্ণ , যতক্ষণ না ফেরতের ধরন উপযুক্ত। মূলত আপনি বলছেন "আমি প্যারামিটারগুলিকে যত্ন করি না"। লক্ষ্য করুন delegate { ... }হয় না একই হিসাবে delegate() { ... }- পরেরটির একটি parameterless প্রতিনিধি ধরনের সঙ্গে শুধুমাত্র সামঞ্জস্যপূর্ণ।
জন স্কিটি

2

উপরের দুটি উদাহরণে কোনও পার্থক্য নেই, শূন্য।

অভিব্যক্তি:

() => { x = 0 }

স্টেটমেন্ট বডি সহ একটি লাম্বদা এক্সপ্রেশন, সুতরাং এটি একটি এক্সপ্রেশন ট্রি হিসাবে সংকলন করা যায় না। আসলে এটি সংকলন করে না কারণ 0 এর পরে এটির জন্য একটি সেমিকোলন প্রয়োজন:

() => { x = 0; } // Lambda statement body
() => x = 0      // Lambda expression body, could be an expression tree. 

6
অবশ্যই এর অর্থ "একটি সংকলন করবে, অন্যটি করবে না" এর পার্থক্য রয়েছে;)
জন স্কিটি

2

অ্যামি বি ঠিক আছে। নোট করুন যে এক্সপ্রেশন ট্রি ব্যবহারের সুবিধা থাকতে পারে। লিনকউ থেকে এসকিউএল এক্সপ্রেশন ট্রি পরীক্ষা করে এটি এসকিউএলে রূপান্তর করবে।

ক্লাস মেম্বারদের নামগুলি কার্যকরভাবে রিফ্যাক্টরিং-নিরাপদ উপায়ে কোনও কাঠামোর কাছে দেওয়ার জন্য আপনি লামডাস এবং এক্সপ্রেশন ট্রি সহ কৌশলগুলি খেলতে পারেন। মোক এর উদাহরণ।


-1

পার্থক্য আছে

উদাহরণ:

var mytask = Task.Factory.StartNew(() =>
{
    Thread.Sleep(5000);
    return 2712;
});
mytask.ContinueWith(delegate
{
    _backgroundTask.ContinueTask(() =>lblPercent.Content = mytask.Result.ToString(CultureInfo.InvariantCulture));
});   

এবং আমি ল্যাম্বদা দিয়ে প্রতিস্থাপন: (ত্রুটি)

var mytask = Task.Factory.StartNew(() =>
{
    Thread.Sleep(5000);
    return 2712;
});
mytask.ContinueWith(()=>
{
    _backgroundTask.ContinueTask(() =>lblPercent.Content = mytask.Result.ToString(CultureInfo.InvariantCulture));
});

ভুল ~ ল্যাম্বদা ব্যর্থ হয়েছে কেবল কারণ প্যারামিটারের স্বাক্ষর মেলে না।
জ্যাক ওয়াং

-1

কিছু বেসিক এখানে।

এটি একটি বেনামি পদ্ধতি

(string testString) => { Console.WriteLine(testString); };

বেনামে পদ্ধতিগুলির নাম না থাকায় আমাদের একটি প্রতিনিধি প্রয়োজন যেখানে আমরা এই দুটি পদ্ধতি বা ভাব প্রকাশ করতে পারি। যেমন

delegate void PrintTestString(string testString); // declare a delegate

PrintTestString print = (string testString) => { Console.WriteLine(testString); }; 
print();

ল্যাম্বডা এক্সপ্রেশন একই। এগুলি ব্যবহার করার জন্য সাধারণত আমাদের একটি প্রতিনিধি প্রয়োজন

s => s.Age > someValue && s.Age < someValue    // will return true/false

এই অভিব্যক্তিটি ব্যবহার করতে আমরা একটি ফানক প্রতিনিধি ব্যবহার করতে পারি।

Func< Student,bool> checkStudentAge = s => s.Age > someValue && s.Age < someValue ;

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