সংকলনটি কেন ঠিক আছে, যখন আমি ফানক <ইন, ইনট> সরাসরি ফিরে আসি এবং যখন ঠিক করি না?


28

আমি এই মামলা বুঝতে পারি না:

public delegate int test(int i);

public test Success()
{
    Func<int, int> f = x => x;
    return f.Invoke; // <- code successfully compiled 
}

public test Fail()
{
    Func<int, int> f = x => x;
    return f; // <- code doesn't compile
}

আমি যখন Invokeপদ্ধতিটি ব্যবহার করি এবং যখন আমি csharp Func<int,int>সরাসরি ফিরে আসি তখন কেন সংকলন ঠিক আছে ?


আপনার একটি প্রতিনিধি রয়েছে যার অর্থ আপনি কোনওরকম ইভেন্ট পাচ্ছেন। ইনভোক ক্রস-থ্রেড ব্যতিক্রমকে বাধা দেয় এবং একাধিক প্রক্রিয়াটিকে অবজেক্টটিতে অ্যাক্সেসের অনুমতি দেয়।
jdweng

মনে রাখবেন যে আপনি দুটি অভিন্ন-প্রতীক প্রতিনিধি যেমন delegate void test1(int i);এবংdelegate void test2(int i);
ম্যাথু ওয়াটসন

উত্তর:


27

এই আচরণটি বুঝতে আপনার দুটি জিনিস জানতে হবে।

  1. সমস্ত প্রতিনিধি থেকে প্রাপ্ত System.Delegate, তবে বিভিন্ন প্রতিনিধিদের বিভিন্ন ধরণের থাকে এবং তাই একে অপরের জন্য বরাদ্দ করা যায় না।
  2. সি # ভাষা কোনও প্রতিনিধিকে কোনও পদ্ধতি বা ল্যাম্বডা নির্ধারণের জন্য বিশেষ হ্যান্ডলিং সরবরাহ করে

কারণ বিভিন্ন প্রতিনিধিদের বিভিন্ন প্রকার রয়েছে, এর অর্থ আপনি এক প্রকারের অন্য কোনও প্রতিনিধি নির্ধারণ করতে পারবেন না।

উদাহরণস্বরূপ, প্রদত্ত:

delegate void test1(int i);
delegate void test2(int i);

তারপর:

test1 a = Console.WriteLine; // Using special delegate initialisation handling.
test2 b = a;                 // Using normal assignment, therefore does not compile.

উপরের প্রথম লাইনটি ঠিকঠাক সঙ্কলন করেছে কারণ এটি কোনও ল্যাম্বডা বা একটি প্রতিনিধিকে কোনও পদ্ধতি নির্ধারণের জন্য বিশেষ হ্যান্ডলিং ব্যবহার করছে।

প্রকৃতপক্ষে, এই লাইনটি কম্পাইলার দ্বারা কার্যকরভাবে এর মতো আবারও লিখেছেন:

test1 a = new test1(Console.WriteLine);

উপরের দ্বিতীয় লাইনটি সংকলন করে না কারণ এটি অন্য ধরণের বেমানান প্রকারকে এক ধরণের উদাহরণ দেওয়ার চেষ্টা করছে।

প্রকারভেদে যতদূর যায়, তার মধ্যে কোনও সামঞ্জস্যপূর্ণ অ্যাসাইনমেন্ট নেই test1এবং test2কারণ এগুলি বিভিন্ন ধরণের।

এটি যদি এটি সম্পর্কে ভাবতে সহায়তা করে তবে এই শ্রেণীর শ্রেণিবিন্যাসটি বিবেচনা করুন:

class Base
{
}

class Test1 : Base
{
}

class Test2 : Base
{
}

নিম্নলিখিত কোড কম্পাইল করা হবে না, যদিও Test1Test2একই বেস ক্লাস থেকে আহরণ করা:

Test1 test1 = new Test1();
Test2 test2 = test1; // Compile error.

এটি ব্যাখ্যা করে যে আপনি কেন একজন প্রতিনিধি প্রকারটিকে অন্য একজনকে নিয়োগ করতে পারবেন না। এটি কেবলমাত্র সাধারণ সি # ভাষা।

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

সুতরাং অবশেষে আপনার প্রশ্নের উত্তর দিতে:

আপনি যখন ব্যবহার করেন Invoke()আপনি কোনও বেমানান প্রকার বরাদ্দ করার পরিবর্তে কোনও প্রতিনিধিকে পদ্ধতি বা ল্যাম্বডাস নির্ধারণের জন্য বিশেষ সি # ল্যাঙ্গুয়েজ হ্যান্ডলিং ব্যবহার করে প্রতিনিধিকে একটি মেথড কল বরাদ্দ করছেন - সুতরাং এটি ঠিক আছে comp

সম্পূর্ণ পরিষ্কার হয়ে উঠতে, কোডটি যা আপনার ওপিতে সংকলন করে:

public test Success()
{
    Func<int, int> f = x => x;
    return f.Invoke; // <- code successfully compiled 
}

আসলে ধারণারূপে এমন কিছুতে রূপান্তরিত হয়:

public test Success()
{
    Func<int, int> f = x => x;
    return new test(f.Invoke);
}

যেখানে ব্যর্থ কোড দুটি অসম্পূর্ণ প্রকারের মধ্যে নির্ধারণের চেষ্টা করছে:

public test Fail()
{
    Func<int, int> f = x => x;
    return f; // Attempting to assign one delegate type to another: Fails
}

6

দ্বিতীয় ক্ষেত্রে, fটাইপ করা হয় Func<int, int>, তবে পদ্ধতিটি বলা হয় যে a test। এগুলি সম্পর্কহীন (প্রতিনিধি) প্রকার, যা একে অপরের কাছে অপরিবর্তনীয়, সুতরাং একটি সংকলক ত্রুটি ঘটে। আপনি ভাষা অনুচ্ছেদের এই বিভাগে যেতে পারেন এবং "প্রতিনিধি" সন্ধান করতে পারেন। একই স্বাক্ষরযুক্ত প্রতিনিধিদের মধ্যে রূপান্তরগুলির কোনও উল্লেখ আপনি পাবেন না।

তবে প্রথম ক্ষেত্রে, f.Invokeএকটি পদ্ধতি গ্রুপ এক্সপ্রেশন , যা আসলে কোনও ধরণের থাকে না। সি # সংকলক একটি পদ্ধতি গ্রুপ রূপান্তরকরণের মাধ্যমে প্রসঙ্গ অনুসারে পদ্ধতি গ্রুপ এক্সপ্রেশনগুলিকে নির্দিষ্ট প্রতিনিধি প্রকারগুলিতে রূপান্তরিত করে

( এখানে 5 ম বুলেট উদ্ধৃত , আমার জোর দেওয়া)

একটি এক্সপ্রেশন নীচের একটি হিসাবে শ্রেণীবদ্ধ করা হয়:

  • ...

  • একটি পদ্ধতি গ্রুপ, যা সদস্য অনুসন্ধানের ফলে ওভারলোডেড পদ্ধতির একটি সেট। [...] একটি পদ্ধতি গোষ্ঠীটিকে একটি আমন্ত্রণ_প্রকাশ, একটি প্রতিনিধি_ক্রিয়েশন_ এক্সপ্রেশন এবং isঅপারেটরের বাম দিক হিসাবে অনুমোদিত হয় এবং সুস্পষ্টভাবে একটি সামঞ্জস্যপূর্ণ প্রতিনিধি প্রকারে রূপান্তর করা যায়।

এই ক্ষেত্রে এটি testপ্রতিনিধি প্রকারে রূপান্তরিত হয় ।

অন্য কথায়, ইতিমধ্যে একটি টাইপ রয়েছে return fবলে কাজ করে না fতবে f.Invokeএখনও টাইপ নেই।


2

এখানে ইস্যুটি টাইপ সামঞ্জস্যতা:

এমএসডিএন সূত্র থেকে ফানকের প্রতিনিধি সংজ্ঞাটি নিম্নলিখিত :

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

আপনি যদি দেখেন যে উপরে বর্ণিত ফানক এবং আপনার সংজ্ঞায়িত প্রতিনিধিদের মধ্যে সরাসরি সম্পর্ক নেই:

public delegate int test(int i);

1 ম স্নিপেট কেন সংকলন করে:

public test Success()
{
    Func<int, int> f = x => x;
    return f.Invoke; // <- code successfully compiled 
 }

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

২ য় স্নিপেট কেন সংকলন করতে ব্যর্থ

ফানক এবং পরীক্ষার প্রতিনিধিদের মধ্যে কোনও প্রকার / অ্যাসাইনমেন্টের সামঞ্জস্যতা নেই, টাইপ সিস্টেমের নিয়মের অংশ হিসাবে ফানক পূরণ করতে পারে না। এমনকি যখন এর ফলাফলটি test delegateপ্রথম ক্ষেত্রে সম্পন্ন হিসাবে নির্ধারিত এবং পূরণ করা যায়।

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