সংকলক দ্ব্যর্থহীন অনুরোধ ত্রুটি - বেনামে পদ্ধতি এবং ফানক <> বা ক্রিয়া সহ পদ্ধতি গ্রুপ


102

আমার একটি দৃশ্য আছে যেখানে আমি কোনও ফাংশন কল করার জন্য বেনাম পদ্ধতিগুলির (বা ল্যাম্বদা সিনট্যাক্স) এর পরিবর্তে পদ্ধতি গ্রুপ সিনট্যাক্সটি ব্যবহার করতে চাই।

ফাংশনটিতে দুটি ওভারলোড রয়েছে, একটি যা একটি নেয় Action, অন্যটি নেয় Func<string>

বেনামে মেথড (বা ল্যাম্বদা সিনট্যাক্স) ব্যবহার করে আমি আনন্দের সাথে দুটি ওভারলোডগুলিতে কল করতে পারি, তবে আমি যদি পদ্ধতি গ্রুপ সিনট্যাক্স ব্যবহার করি তবে দ্ব্যর্থহীন অনুরোধের একটি সংকলক ত্রুটি পেয়েছি। আমি স্পষ্টভাবে কাস্টিং Actionবা এর মাধ্যমে সমাধান করতে Func<string>পারি, তবে মনে করি না এটি প্রয়োজনীয় হওয়া উচিত।

সুস্পষ্ট কাস্ট কেন প্রয়োজন হবে তা যে কেউ ব্যাখ্যা করতে পারেন।

নীচে কোড নমুনা।

class Program
{
    static void Main(string[] args)
    {
        ClassWithSimpleMethods classWithSimpleMethods = new ClassWithSimpleMethods();
        ClassWithDelegateMethods classWithDelegateMethods = new ClassWithDelegateMethods();

        // These both compile (lambda syntax)
        classWithDelegateMethods.Method(() => classWithSimpleMethods.GetString());
        classWithDelegateMethods.Method(() => classWithSimpleMethods.DoNothing());

        // These also compile (method group with explicit cast)
        classWithDelegateMethods.Method((Func<string>)classWithSimpleMethods.GetString);
        classWithDelegateMethods.Method((Action)classWithSimpleMethods.DoNothing);

        // These both error with "Ambiguous invocation" (method group)
        classWithDelegateMethods.Method(classWithSimpleMethods.GetString);
        classWithDelegateMethods.Method(classWithSimpleMethods.DoNothing);
    }
}

class ClassWithDelegateMethods
{
    public void Method(Func<string> func) { /* do something */ }
    public void Method(Action action) { /* do something */ }
}

class ClassWithSimpleMethods
{
    public string GetString() { return ""; }
    public void DoNothing() { }
}

সি # 7.3 আপডেট

20 মার্চ 2019 তে নীচে 0 সিসিডি'র মন্তব্য অনুসারে (আমি এই প্রশ্নটি পোস্ট করার নয় বছর পরে!), এই কোডটি সি # 7.3 হিসাবে সংকলিত উন্নত ওভারলোড প্রার্থীদের ধন্যবাদ ।


আমি আপনার কোডটি চেষ্টা করেছি এবং আমি একটি অতিরিক্ত সংকলন সময় ত্রুটি পেয়েছি: 'শূন্য পরীক্ষা lass ক্লাস উইথসিম্পলমিথডস .ডুথিং কিছুই ()' -র ভুল রিটার্ন টাইপ রয়েছে (যা লাইন 25-এ রয়েছে, যেখানে দ্ব্যর্থতার ত্রুটি রয়েছে)
ম্যাট এলেন

@ ম্যাট: আমি ত্রুটিটিও দেখতে পাচ্ছি। আমার পোস্টে যে ত্রুটিগুলি আমি উদ্ধৃত করেছি তা হ'ল সংকলনের সমস্যাগুলি যা ভিএস হাইলাইট করে আপনি এমনকি একটি পূর্ণ সংকলন চেষ্টা করার আগে।
রিচার্ড ইভ

1
যাইহোক, এটি একটি দুর্দান্ত প্রশ্ন ছিল। আমি এমন কোনও কিছুকেই পছন্দ করি যা আমাকে চশমাগুলিতে বাধ্য করে :)
জন স্কিটি

1
মনে রাখবেন যে আপনার নমুনা কোড যদি C # এর 7.3 (ব্যবহার কম্পাইল হবে <LangVersion>7.3</LangVersion>) অথবা পরে ধন্যবাদ উন্নত জমিদার প্রার্থীদের
0xced

উত্তর:


97

প্রথমে, আমি শুধু বলি যে জনের উত্তরটি সঠিক। এটি অনুমানের চুলের অন্যতম অঙ্গ, প্রথমে এটিতে মাথা ঘুরিয়ে দেওয়ার জন্য জনের পক্ষে খুব ভাল।

দ্বিতীয়ত, আমাকে এই লাইনটি বলতে দিন:

একটি পদ্ধতি গ্রুপ থেকে একটি সামঞ্জস্যপূর্ণ প্রতিনিধি প্রকারে একটি অন্তর্নিহিত রূপান্তর বিদ্যমান

(জোর দেওয়া) গভীরভাবে বিভ্রান্তিকর এবং দুর্ভাগ্যজনক। আমি এখানে "সামঞ্জস্যপূর্ণ" শব্দটি মুছে ফেলার বিষয়ে ম্যাডসের সাথে কথা বলব।

এটি বিভ্রান্তিকর এবং দুর্ভাগ্যজনক কারণ হ'ল কারণ দেখে মনে হচ্ছে এটি 15.2 ধারা, "ডেলিগেট সামঞ্জস্যতা" এ ডাকছে calling বিভাগ 15.2 পদ্ধতি এবং প্রতিনিধি প্রকারের মধ্যে সামঞ্জস্য সম্পর্কের বর্ণনা দিয়েছিল , তবে এটি পদ্ধতি গ্রুপ এবং প্রতিনিধি প্রকারের রূপান্তরতার প্রশ্ন , যা আলাদা।

এখন যে আমরা এটি অতিক্রম করেছি, আমরা অনুমানের of..6 অনুচ্ছেদটি ধরে চলতে পারি এবং কী পাই তা দেখতে পারি।

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

class Program
{
    delegate void D1();
    delegate string D2();
    static string X() { return null; }
    static void Y(D1 d1) {}
    static void Y(D2 d2) {}
    static void Main()
    {
        Y(X);
    }
}

সুতরাং আসুন এটি লাইন লাইন মাধ্যমে যেতে।

একটি পদ্ধতি গ্রুপ থেকে একটি সামঞ্জস্যপূর্ণ প্রতিনিধি প্রকারে একটি অন্তর্নিহিত রূপান্তর বিদ্যমান।

"সামঞ্জস্যপূর্ণ" শব্দটি এখানে দুর্ভাগ্যজনক কিনা তা আমি ইতিমধ্যে আলোচনা করেছি। সরানো. ওয়াই (এক্স) এর উপর ওভারলোড রেজোলিউশন করার সময় আমরা ভাবছি, পদ্ধতি গ্রুপ এক্স কি ডি 1 তে রূপান্তর করে? এটি কি ডি 2 তে রূপান্তর করে?

একটি প্রতিনিধি টাইপ ডি এবং একটি এক্সপ্রেশন E দেওয়া হয়েছে যা পদ্ধতি গ্রুপ হিসাবে শ্রেণিবদ্ধ করা হয়েছে, E থেকে D তে একটি অন্তর্নিহিত রূপান্তর উপস্থিত রয়েছে যদি E এর কমপক্ষে একটি পদ্ধতি প্রযোজ্য তবে এটি [...] পরামিতি ব্যবহার করে নির্মিত একটি আর্গুমেন্ট তালিকায় অন্তর্ভুক্ত ধরণের প্রকার ও সংশোধক, নিম্নে বর্ণিত।

এ পর্যন্ত সব ঠিকই. এক্সে এমন একটি পদ্ধতি থাকতে পারে যা D1 বা D2 এর যুক্তি তালিকার সাথে প্রযোজ্য।

একটি পদ্ধতি গোষ্ঠী E থেকে একটি প্রতিনিধি প্রকার D তে রূপান্তরকরণের সংকলন-সময় অ্যাপ্লিকেশনটি নীচে বর্ণিত হয়েছে।

এই লাইনটি সত্যিই আকর্ষণীয় কিছু বলে না।

নোট করুন যে E থেকে D তে অন্তর্নিহিত রূপান্তরটির অস্তিত্ব কোনও গ্যারান্টি দেয় না যে রূপান্তরটির সংকলন-সময় অ্যাপ্লিকেশনটি ত্রুটি ছাড়াই সফল হবে।

এই লাইন আকর্ষণীয়। এর অর্থ হ'ল এখানে অন্তর্নিহিত রূপান্তর রয়েছে যা বিদ্যমান তবে যা ত্রুটিতে রূপান্তরিত হতে পারে! এটি সি # এর উদ্ভট নিয়ম। একটি মুহুর্তটি আবিষ্কার করতে এখানে একটি উদাহরণ দেওয়া হয়েছে:

void Q(Expression<Func<string>> f){}
string M(int x) { ... }
...
int y = 123;
Q(()=>M(y++));

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

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

সরানো:

E (A) ফর্মের একটি পদ্ধতিতে অনুরোধের সাথে মিল রেখে একটি একক পদ্ধতি এম নির্বাচন করা হয়েছে [...] আর্গুমেন্ট তালিকা এ হ'ল এক্সপ্রেশনগুলির একটি তালিকা, প্রতিটি ফর্মালটিতে সংশ্লিষ্ট প্যারামিটারের একটি চলক [...] হিসাবে শ্রেণিবদ্ধ -ডিটারের পরিমিতি-তালিকা

ঠিক আছে. সুতরাং আমরা ডি 1 এর সাথে সম্মতিতে ওভারলোড রেজোলিউশন করি। ডি 1 এর আনুষ্ঠানিক প্যারামিটারের তালিকাটি খালি, সুতরাং আমরা এক্স () এবং আনন্দের উপর ওভারলোড রেজোলিউশন করি, আমরা একটি পদ্ধতি "স্ট্রিং এক্স ()" খুঁজে পেয়েছি যা কাজ করে। একইভাবে, ডি 2-এর আনুষ্ঠানিক প্যারামিটার তালিকাটি খালি is আবার, আমরা দেখতে পাই যে "স্ট্রিং এক্স ()" এমন একটি পদ্ধতি যা এখানে খুব কার্যকর হয়।

এখানে নীতিটি হ'ল পদ্ধতি গোষ্ঠী রূপান্তরকরণ নির্ধারণের জন্য ওভারলোড রেজোলিউশন ব্যবহার করে কোনও পদ্ধতি গোষ্ঠী থেকে একটি পদ্ধতি নির্বাচন করা প্রয়োজন এবং ওভারলোড রেজোলিউশন রিটার্নের ধরণগুলি বিবেচনা করে না

যদি অ্যালগরিদম [...] ত্রুটি সৃষ্টি করে তবে একটি সংকলন-সময় ত্রুটি ঘটে। অন্যথায় অ্যালগরিদম একটি একক সেরা পদ্ধতি এম উত্পাদন করে যা ডি এর সমান সংখ্যক পরামিতি রয়েছে এবং রূপান্তরটি বিদ্যমান বলে মনে করা হয়।

এক্স গ্রুপের গ্রুপে কেবল একটি পদ্ধতি রয়েছে তাই এটি অবশ্যই সেরা হতে হবে। আমরা সফলভাবে প্রমাণ করেছি যে এক্স থেকে ডি 1 এবং এক্স থেকে ডি 2 এ রূপান্তর বিদ্যমান exists

এখন, এই লাইনটি কি প্রাসঙ্গিক?

নির্বাচিত পদ্ধতি এম অবশ্যই প্রতিনিধি টাইপ ডি এর সাথে সামঞ্জস্যপূর্ণ বা অন্যথায় একটি সংকলন-সময় ত্রুটি দেখা দেয়।

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

এখন, কেউ অবশ্যই তর্ক করতে পারে যে বৈধ রূপান্তরটি ত্রুটি তৈরির চেয়ে আরও ভাল। এরপরে কার্যকরভাবে বলা হবে, এই ক্ষেত্রে, ওভারলোড রেজোলিউশন রিটার্নের ধরণগুলি বিবেচনা করে, যা আমরা এড়াতে চাই। তারপরে প্রশ্নটি কোন নীতিটি আরও ভাল: (1) ওভারলোডের রেজোলিউশন রিটার্নের ধরণগুলি বিবেচনা করে না এমন আক্রমণকারী বজায় রাখবে বা (২) এমন একটি রূপান্তর বাছাই করার চেষ্টা করুন যা আমরা জানি যে আমরা জানি না তার উপর কাজ করবে?

এটি একটি রায় কল। সঙ্গে lambdas , আমরা কি করতে , ধর্মান্তর এই প্রকারের মধ্যে রিটার্ন টাইপ বিবেচনা অধ্যায় 7.4.3.3 দেখুন:

ই একটি বেনামে ফাংশন, টি 1 এবং টি 2 হ'ল সমান প্যারামিটার তালিকাগুলি সহ প্রতিনিধি প্রকার বা এক্সপ্রেশন ট্রি ট্রিটস, সেই প্যারামিটার তালিকার প্রসঙ্গে ইয়ের জন্য একটি অনুমানযুক্ত রিটার্ন টাইপ এক্স উপস্থিত রয়েছে এবং নিম্নলিখিতগুলির মধ্যে একটি হোল্ড করে:

  • টি 1 এর রিটার্ন টাইপ ওয়াই 1 রয়েছে, এবং টি 2 এর রিটার্ন টাইপ ওয়াই 2 রয়েছে এবং এক্স থেকে Y1 তে রূপান্তরটি এক্স থেকে Y2 রূপান্তর চেয়ে ভাল

  • টি 1 এর রিটার্ন টাইপ ওয়াই থাকে এবং টি 2 হ'ল বাতিল হয়

দুর্ভাগ্যজনক যে পদ্ধতি গ্রুপ রূপান্তর এবং ল্যাম্বদা রূপান্তরগুলি এই ক্ষেত্রে অসঙ্গত। তবে আমি এর সাথে বেঁচে থাকতে পারি

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


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

35

সম্পাদনা: আমি মনে করি এটি পেয়েছি।

Zinglon বলছেন, এটা সেখান থেকে একটি অন্তর্নিহিত রূপান্তর কারণ এর GetStringথেকে Actionযদিও কম্পাইল-টাইম আবেদন ব্যর্থ হবে। এখানে কিছু জোর দিয়ে (খনি) .6..6 বিভাগের সাথে পরিচয় করিয়ে দেওয়া হয়েছে:

একটি অন্তর্নিহিত রূপান্তর (.16.1) একটি পদ্ধতি গোষ্ঠী (§7.1) থেকে সামঞ্জস্যপূর্ণ প্রতিনিধি প্রকারে উপস্থিত রয়েছে। একটি প্রতিনিধি টাইপ ডি এবং একটি এক্সপ্রেশন ই দেওয়া হয়েছে যা একটি পদ্ধতি গ্রুপ হিসাবে শ্রেণিবদ্ধ করা হয়েছে, যদি E এর অন্তত একটি পদ্ধতি থাকে যা তার স্বাভাবিক আকারে প্রযোজ্য (§7.4.3.1) নির্মিত আর্গুমেন্ট তালিকায় অন্তর্ভুক্ত হয় তবে একটি অন্তর্নিহিত রূপান্তর E থেকে D তে উপস্থিত থাকে E নীচে বর্ণিত হিসাবে প্যারামিটার ধরণের এবং ডি এর সংশোধক ব্যবহার করে।

এখন, আমি প্রথম বাক্যে বিভ্রান্ত হয়ে যাচ্ছিলাম - যা একটি সামঞ্জস্যপূর্ণ প্রতিনিধি প্রকারের রূপান্তর সম্পর্কে কথা বলে। পদ্ধতি গোষ্ঠীর Actionকোনও পদ্ধতির জন্য উপযুক্ত নয় GetString, তবে GetString()পদ্ধতিটি তার স্বাভাবিক আকারে প্যারামিটারের ধরণের এবং ডি এর সংশোধক ব্যবহার করে নির্মিত একটি যুক্তি তালিকার জন্য প্রযোজ্য তা নোট করুন যে এটির রিটার্নের ধরণের বিষয়ে কথা হয় না ডি। এজন্যই এটি বিভ্রান্ত হচ্ছে ... কারণ এটি কেবল রূপান্তরটি প্রয়োগ করার GetString()সময় তার প্রতিনিধিদের সামঞ্জস্যতা পরীক্ষা করে, এর অস্তিত্বের জন্য যাচাই করে না।

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

using System;

class Program
{
    static void ActionMethod(Action action) {}
    static void IntMethod(int x) {}

    static string GetString() { return ""; }

    static void Main(string[] args)
    {
        IntMethod(GetString);
        ActionMethod(GetString);
    }
}

Mainউভয়ই সংকলনগুলিতে পদ্ধতিটির অনুরোধের এক্সপ্রেশন নয়, ত্রুটি বার্তাগুলি আলাদা। এখানে একটি IntMethod(GetString):

Test.cs (12,9): ত্রুটি CS1502: 'প্রোগ্রাম.IntMethod (int)' র জন্য সর্বোত্তম ওভারলোডেড পদ্ধতি ম্যাচটিতে কিছু অবৈধ যুক্তি রয়েছে

অন্য কথায়, অনুমানের ধারা 7.4.3.1 কোনও প্রযোজ্য ফাংশনের সদস্যদের খুঁজে পাবে না find

এখন এখানে ত্রুটি রয়েছে ActionMethod(GetString):

টেস্ট.সি.এস (১৩,২২): ত্রুটি CS0407: 'স্ট্রিং প্রোগ্রাম.গেটস্ট্রিং ()' এর ভুল রিটার্ন টাইপ রয়েছে

এবার এটি যে পদ্ধতিতে কল করতে চায় তা কার্যকর করেছে - তবে এটি প্রয়োজনীয় রূপান্তর সম্পাদন করতে ব্যর্থ হয়েছে। দুর্ভাগ্যক্রমে আমি যেখানে চূড়ান্ত চেকটি সম্পন্ন করা হয় সেই নির্দিষ্ট কিছুটির সন্ধান করতে পারি না - দেখে মনে হচ্ছে এটি 7.5.5.1 এর মধ্যে হতে পারে তবে আমি ঠিক কোথায় দেখতে পাচ্ছি না।


এই বিটটি বাদে পুরানো উত্তর সরিয়ে দেওয়া হয়েছে - কারণ আমি আশা করি এরিক এই প্রশ্নের "কেন" এর উপর আলোকপাত করতে পারে ...

এখনও খুঁজছি ... মাঝামাঝি সময়ে, আমরা যদি তিনবার "এরিক লিপার্ট" বলি, আপনি কি মনে করেন যে আমরা একটি পরিদর্শন করব (এবং এইভাবে একটি উত্তর)?


@ জন - এটি কি হতে পারে classWithSimpleMethods.GetStringএবং classWithSimpleMethods.DoNothingপ্রতিনিধি নাও হতে পারে ?
ড্যানিয়েল এ। হোয়াইট

@ ড্যানিয়েল: না - এই অভিব্যক্তিগুলি মেথড গ্রুপ এক্সপ্রেশন এবং ততক্ষণ ওভারলোডেড পদ্ধতিগুলি কেবল তখন প্রযোজ্য হিসাবে বিবেচিত হওয়া উচিত যখন কোনও পদ্ধতি গ্রুপ থেকে প্রাসঙ্গিক প্যারামিটার ধরণের অন্তর্ভুক্ত রূপান্তর থাকে there's অনুমানের 7.4.3.1 বিভাগ দেখুন।
জন স্কিটি

Section. section অধ্যায়টি পড়া, দেখে মনে হচ্ছে এটি ক্লাস উইথসিম্পলমিথডস থেকে রূপান্তরিত হয়েছে G গেট স্ট্রিং অ্যাকশন হিসাবে উপস্থিত হিসাবে বিবেচিত হয় যেহেতু প্যারামিটারের তালিকাগুলি সামঞ্জস্যপূর্ণ, তবে রূপান্তর (যদি চেষ্টা করা হয়) সংকলনের সময় ব্যর্থ হয়। অতএব, একটি অন্তর্নিহিত রূপান্তর করে উভয় প্রতিনিধি প্রকারের বিদ্যমান এবং কল অস্পষ্ট।
জিঙ্গলন

@zinglon: আপনি কিভাবে পড়ছেন §6.6 নির্ধারণ থেকে একটি রূপান্তর ClassWithSimpleMethods.GetStringকরতে Actionবৈধ? একটি পদ্ধতি জন্য Mএকটি প্রতিনিধি ধরনের সঙ্গে সামঞ্জস্যপূর্ণ হতে D(§15.2) "একটি পরিচয় বা অন্তর্নিহিত রেফারেন্স রূপান্তর রিটার্ন টাইপ থেকে বিদ্যমান Mফেরত টাইপ D।"
জেসন

@ জেসন: ধারণাটি রূপান্তরটি বৈধ বলে উল্লেখ করে না, এটি বলে যে এটি বিদ্যমান । প্রকৃতপক্ষে, এটি সংকলনের সময় ব্যর্থ হওয়ায় এটি অবৈধ। Two6.6 এর প্রথম দুটি পয়েন্ট রূপান্তরটি বিদ্যমান কিনা তা নির্ধারণ করে। নিম্নলিখিত পয়েন্টগুলি রূপান্তরটি সফল হবে কিনা তা নির্ধারণ করে। বিন্দু 2 থেকে: "অন্যথায় অ্যালগরিদম একটি একক সর্বোত্তম পদ্ধতি এম উত্পাদন করে যা ডি এর সমান সংখ্যক পরামিতিযুক্ত থাকে এবং রূপান্তরটি বিদ্যমান বলে মনে করা হয়" " §15.2 পয়েন্ট 3 এ আহ্বান জানানো হয়েছে
জিংলন

1

মুছে ফেলাতে Func<string>এবং Action<string>(স্পষ্টতই খুব আলাদা Actionএবং এর সাথে Func<string>) ব্যবহার করা ClassWithDelegateMethodsঅস্পষ্টতা দূর করে।

অস্পষ্টতা এছাড়াও মধ্যে ঘটে Actionএবং Func<int>

আমি এটি দিয়ে অস্পষ্টতা ত্রুটিটিও পেয়েছি:

class Program
{ 
    static void Main(string[] args) 
    { 
        ClassWithSimpleMethods classWithSimpleMethods = new ClassWithSimpleMethods(); 
        ClassWithDelegateMethods classWithDelegateMethods = new ClassWithDelegateMethods(); 

        classWithDelegateMethods.Method(classWithSimpleMethods.GetOne);
    } 
} 

class ClassWithDelegateMethods 
{ 
    public void Method(Func<int> func) { /* do something */ }
    public void Method(Func<string> func) { /* do something */ } 
}

class ClassWithSimpleMethods 
{ 
    public string GetString() { return ""; } 
    public int GetOne() { return 1; }
} 

আরও পরীক্ষা-নিরীক্ষা দেখায় যে কোনও পদ্ধতি গোষ্ঠী নিজে থেকে পাস করার সময় কোন ওভারলোড ব্যবহার করবেন তা নির্ধারণের সময় রিটার্নের ধরণটি সম্পূর্ণ উপেক্ষা করা হয়।

class Program
{
    static void Main(string[] args)
    {
        ClassWithSimpleMethods classWithSimpleMethods = new ClassWithSimpleMethods();
        ClassWithDelegateMethods classWithDelegateMethods = new ClassWithDelegateMethods();

        //The call is ambiguous between the following methods or properties: 
        //'test.ClassWithDelegateMethods.Method(System.Func<int,int>)' 
        //and 'test.ClassWithDelegateMethods.Method(test.ClassWithDelegateMethods.aDelegate)'
        classWithDelegateMethods.Method(classWithSimpleMethods.GetX);
    }
}

class ClassWithDelegateMethods
{
    public delegate string aDelegate(int x);
    public void Method(Func<int> func) { /* do something */ }
    public void Method(Func<string> func) { /* do something */ }
    public void Method(Func<int, int> func) { /* do something */ }
    public void Method(Func<string, string> func) { /* do something */ }
    public void Method(aDelegate ad) { }
}

class ClassWithSimpleMethods
{
    public string GetString() { return ""; }
    public int GetOne() { return 1; }
    public string GetX(int x) { return x.ToString(); }
} 

0

সঙ্গে ওভারলোডিং Funcএবং Actionসদৃশ হয় (কারণ তাদের উভয়ের প্রতিনিধিদের হয়)

string Function() // Func<string>
{
}

void Function() // Action
{
}

আপনি যদি খেয়াল করেন, সংকলকটি কোনটি কল করবে তা জানে না কারণ তারা কেবল ফিরতি ধরণের দ্বারা পৃথক।


আমি মনে করি না এটা সত্যিই বেশ যে মত - কারণ আপনি একটি রূপান্তর করতে পারবেন না Func<string>একটি মধ্যে Action... এবং আপনি একটি পদ্ধতি শুধুমাত্র একটি পদ্ধতি যা একটি মধ্যে একটি স্ট্রিং ফেরৎ নিয়ে গঠিত গ্রুপ রূপান্তর করতে পারবেন না Actionপারেন।
জন স্কিটি

2
আপনি একটি প্রতিনিধি কোন প্যারামিটার এবং আয় আছে নিক্ষেপ করতে পারবে না stringএকটি থেকে Action। দ্বিধা কেন আছে তা আমি দেখছি না।
জেসন

3
@ ডিটিবি: হ্যাঁ, ওভারলোডিং অপসারণ করা সমস্যাটিকে সরিয়ে দেয় - তবে কেন সমস্যা আছে তা সত্যিই ব্যাখ্যা করে না।
জন স্কিটি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.