কেন কোনও বেনামি পদ্ধতি ভারতে বরাদ্দ করা যায় না?


139

আমার কাছে নিম্নলিখিত কোড রয়েছে:

Func<string, bool> comparer = delegate(string value) {
    return value != "0";
};

তবে, নিম্নলিখিতগুলি সংকলন করে না:

var comparer = delegate(string value) {
    return value != "0";
};

সংকলকটি এটির একটি হিসাবে কেন বের করতে পারে না Func<string, bool>? এটিতে একটি স্ট্রিং প্যারামিটার লাগে এবং একটি বুলিয়ান দেয়। পরিবর্তে, এটি আমাকে ত্রুটি দেয়:

কোনও ছদ্মবেশী-টাইপ করা স্থানীয় ভেরিয়েবলকে বেনামে পদ্ধতি বরাদ্দ করতে পারে না।

আমার একটি অনুমান আছে এবং তা হ'ল যদি ভার্সন সংস্করণটি সংকলিত হয় তবে আমার যদি নিম্নলিখিতগুলি থাকে তবে এটির ধারাবাহিকতার অভাব হবে:

var comparer = delegate(string arg1, string arg2, string arg3, string arg4, string arg5) {
    return false;
};

উপরের অর্থগুলি বোঝায় না যেহেতু ফানক <> কেবল 4 টি পর্যন্ত আর্গুমেন্টের অনুমতি দেয় (নেট। 3.5 এ, যা আমি ব্যবহার করছি)। সম্ভবত কেউ সমস্যা স্পষ্ট করতে পারে। ধন্যবাদ।


3
আপনার 4 টি আর্গুমেন্ট আর্গুমেন্ট সম্পর্কে নোট করুন । নেট 4 এ Func<>16 টি আর্গুমেন্ট গ্রহণ করে।
অ্যান্টনি পেগ্রাম

স্পষ্টতার জন্য ধন্যবাদ। আমি .NET 3.5 ব্যবহার করছি।
মার্লন

9
সংকলককে কেন এটি ভাববে Func<string, bool>? মনে হচ্ছে Converter<string, bool>আমার কাছে!
বেন ভয়েগ্ট


3
কখনও কখনও আমি ভিবি মিস করি ..Dim comparer = Function(value$) value <> "0"
স্লাই

উত্তর:


155

অন্যরা ইতিমধ্যে উল্লেখ করেছে যে অসম্ভবভাবে সম্ভব অনেক প্রতিনিধি প্রকার রয়েছে যা আপনি বোঝাতে পারতেন ; তাই বিশেষ সম্পর্কে কি Funcএটি পরিবর্তে ডিফল্ট হতে দাবী Predicateবা Actionবা অন্য কোন সম্ভাবনা? এবং, লাম্বদাসের জন্য, কেন এটি স্পষ্ট যে অভিপ্রায় গাছের ফর্মের চেয়ে প্রতিনিধি ফর্মটি বেছে নেওয়ার উদ্দেশ্য?

তবে আমরা বলতে পারি যে Funcএটি বিশেষ, এবং লাম্বদা বা বেনামে পদ্ধতির অনুমিত ধরণটি কোনও কিছুর ফানক। আমাদের এখনও সব ধরণের সমস্যা আছে। নিম্নলিখিত মামলার জন্য আপনি কোন ধরণের অনুমিত হতে চান?

var x1 = (ref int y)=>123;

এমন কোনও Func<T>ধরণের নেই যা কোনও রেফ নেয়।

var x2 = y=>123;

আমরা ফর্মাল প্যারামিটারের ধরণটি জানি না, যদিও আমরা রিটার্নটি জানি। (বা আমরা কি? রিটার্নটি কি দীর্ঘ? সংক্ষিপ্ত? বাইট?)

var x3 = (int y)=>null;

আমরা রিটার্নের ধরণ জানি না, তবে এটি বাতিল হওয়া যায় না। রিটার্নের ধরণটি কোনও রেফারেন্স টাইপ বা কোনও মূল্যহীন মান প্রকার হতে পারে।

var x4 = (int y)=>{ throw new Exception(); }

আবার, আমরা রিটার্নের ধরণটি জানি না এবং এবার এটি বাতিল হতে পারে।

var x5 = (int y)=> q += y;

এটি কি শূন্য-প্রত্যাবর্তনকারী বিবৃতি ল্যাম্বদা বা এমন কিছু যা Q এর জন্য নির্ধারিত মানটি ফেরত দেয়? উভয়ই আইনী; আমাদের কোনটি বেছে নেওয়া উচিত?

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

পরিস্থিতি যেখানে এটি আসলে কার্যকর তা হ'ল:

var xAnon = (int y)=>new { Y = y };

কারণ সেই জিনিসটির জন্য কোনও "স্পিকারে" টাইপ নেই। তবে আমাদের সর্বদা এই সমস্যাটি রয়েছে এবং আমরা প্রকারটি অনুমিত করতে কেবল পদ্ধতি ধরণের অনুক্রম ব্যবহার করি:

Func<A, R> WorkItOut<A, R>(Func<A, R> f) { return f; }
...
var xAnon = WorkItOut((int y)=>new { Y = y });

এবং এখন পদ্ধতি টাইপ অনুমানটি ফানক প্রকারটি কী তা বোঝায়।


43
আপনি কখন নিজের এসও উত্তরগুলি বইয়ে সংকলন করতে যাচ্ছেন? আমি এটি কিনেছি :)
ম্যাট গ্রেয়ার

13
আমি এসও এর উত্তরগুলির এরিক লিপার্ট বইয়ের প্রস্তাবটি দ্বিতীয় করলাম। প্রস্তাবিত শিরোনাম: "স্ট্যাক থেকে প্রতিচ্ছবি"
অ্যাডাম র্যাকিস

24
@ এরিক: ভাল উত্তর, তবে এটি একেবারেই সম্ভব নয় এমন কিছু হিসাবে বর্ণনা করার জন্য এটি সামান্য বিভ্রান্তিকর, কারণ এটি আসলে ডি তে সম্পূর্ণ সূক্ষ্মভাবে কাজ করে এটি ঠিক যে আপনি ছেলেরা তাদের নিজস্ব ধরণের প্রতিনিধিদের দেওয়া পছন্দ করেন নি, এবং পরিবর্তে তাদেরকে নির্ভর করে তোলে তাদের প্রসঙ্গে ... সুতরাং আইএমএইচও এর উত্তর হওয়া উচিত "কারণ আমরা এটি কীভাবে তৈরি করেছি" অন্য যে কোনও কিছুর চেয়ে বেশি। :)
user541686

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

7
@ অ্যাবস্ট্রাক্ট ডিসসন্যান্স: সীমিত সংস্থানসমূহের বিকাশকারী এবং সময় অনুসারে আমরা ব্যয়টি পরিমাপ করেছি। এই দায়িত্ব godশ্বরের দ্বারা দেওয়া হয়নি; এটি বিকাশকারী বিভাগের সহ-সভাপতি দ্বারা আরোপিত হয়েছিল। যে ধারণাটি কোনওভাবেই সি # দল বাজেট প্রক্রিয়াটিকে উপেক্ষা করতে পারে তা এক আজব বিষয়। আমি আপনাকে আশ্বাস দিচ্ছি, ট্রেড অফগুলি সেই বিশেষজ্ঞদের সতর্কতার সাথে বিবেচনা করে বিবেচনা করা হয়েছিল যারা সি # সম্প্রদায়গুলির শুভেচ্ছাকে প্রকাশ করেছিল, মাইক্রোসফ্টের জন্য কৌশলগত মিশন এবং নকশায় তাদের নিজস্ব স্বাদ পছন্দ করেছে taste
এরিক লিপার্ট

29

শুধুমাত্র এরিক লিপার্ট নিশ্চিতভাবেই জানেন, তবে আমি মনে করি কারণ প্রতিনিধি প্রকারের স্বাক্ষরটি স্বতন্ত্রভাবে প্রকারটি নির্ধারণ করে না।

আপনার উদাহরণ বিবেচনা করুন:

var comparer = delegate(string value) { return value != "0"; };

কী হওয়া varউচিত তার জন্য এখানে দুটি সম্ভাব্য তথ্যসূত্র রয়েছে :

Predicate<string> comparer  = delegate(string value) { return value != "0"; };  // okay
Func<string, bool> comparer = delegate(string value) { return value != "0"; };  // also okay

কোনটি সংকলক অনুমান করা উচিত? একটি বা অন্যটি বেছে নেওয়ার কোনও ভাল কারণ নেই। এবং যদিও একটি কার্যকরভাবে একটি এর Predicate<T>সমতুল্য Func<T, bool>, তবুও তারা .NET টাইপ সিস্টেমের স্তরে বিভিন্ন ধরণের। সংকলক অতএব নির্বিঘ্নে প্রতিনিধি প্রকারটি সমাধান করতে পারে না এবং অবশ্যই প্রকারের অনুক্রমটি ব্যর্থ করতে হবে।


1
আমি নিশ্চিত মাইক্রোসফ্টের বেশ কয়েকটি অন্যান্য লোকও এটি নিশ্চিতভাবে জানে। ;) তবে হ্যাঁ, আপনি একটি প্রধান কারণকে বোঝান, সংকলনের সময় প্রকারটি নির্ধারণ করা যায় না কারণ সেখানে কিছুই নেই। ভাষা নির্দিষ্টকরণের 8.5.1 বিভাগটি বেনাম ফাংশনগুলিকে স্পষ্টভাবে টাইপড ভেরিয়েবল ঘোষণায় ব্যবহার করা থেকে বঞ্চিত করার জন্য এই কারণটি বিশেষভাবে হাইলাইট করে।
অ্যান্টনি পেগ্রাম

3
হাঁ। আরও খারাপ, ল্যাম্বডাসের জন্য আমরা এটিও জানি না যে এটি কোনও প্রতিনিধি প্রকারের দিকে যাচ্ছে কিনা; এটি একটি অভিব্যক্তি গাছ হতে পারে।
এরিক লিপার্ট

আগ্রহী যে কারও জন্য, আমি এই সম্পর্কে আরও কিছু লিখেছিলাম এবং সি # এবং এফ # কীভাবে মনস্তিষ্টকিউ
ব্লগ /


কীভাবে তারা ".NET টাইপ সিস্টেমের স্তরে" পার্থক্য করে?
aराव6

6

এরিক লিপার্টের যেখানে রয়েছে সে সম্পর্কে একটি পুরাতন পোস্ট রয়েছে

এবং আসলে সি # 2.0 স্পেসিফিকেশন এটিকে কল করে। পদ্ধতি গোষ্ঠী এক্সপ্রেশন এবং বেনামী পদ্ধতি এক্সপ্রেশন হ'ল সি # 2.0 এ টাইপলেস এক্সপ্রেশন এবং ল্যাম্বডা এক্সপ্রেশন তাদের সাথে সি # 3.0 এ যোগ দেয়। সুতরাং তাদের পক্ষে নিষ্ক্রিয় ঘোষণার ডানদিকে "নগ্ন" প্রদর্শিত অবৈধ।


এবং এটি ভাষা নির্দিষ্টকরণের 8.5.1 বিভাগ দ্বারা আন্ডারকর্ড করা হয়েছে। সুস্পষ্টভাবে টাইপ করা স্থানীয় ভেরিয়েবলের জন্য "ইনিশিয়ালাইজার এক্সপ্রেশনটির একটি সংকলন-টাইপ টাইপ থাকতে হবে"।
অ্যান্টনি পেগ্রাম

5

বিভিন্ন প্রতিনিধি বিভিন্ন ধরণের বিবেচিত হয়। উদাহরণস্বরূপ, এর Actionচেয়ে পৃথক MethodInvoker, এবং একটি উদাহরণটি Actionকোনও ভেরিয়েবলের কাছে বরাদ্দ করা যায় না MethodInvoker

সুতরাং, যেমন একটি বেনামী প্রতিনিধি দেওয়া (বা ল্যাম্বদা) দেওয়া () => {}, এটি একটি Actionবা একটি MethodInvoker? সংকলকটি বলতে পারে না।

একইভাবে, যদি আমি কোনও প্রতিনিধি প্রকারটি stringআর্গুমেন্ট গ্রহণ করে এবং একটি ফেরত দেওয়ার ঘোষণা করি তবে সংকলকটি boolকীভাবে জানতে পারবে যে আপনি Func<string, bool>আমার প্রতিনিধি প্রকারের পরিবর্তে সত্যিই একটি চেয়েছিলেন ? এটি প্রতিনিধি প্রকারটি অনুমান করতে পারে না।


2

নিখুঁতভাবে টাইপ করা স্থানীয় ভেরিয়েবলগুলি সম্পর্কিত MSDN থেকে নীচের বিষয়গুলি:

  1. ভেরি কেবল তখনই ব্যবহার করা যেতে পারে যখন স্থানীয় ভেরিয়েবল একই বিবৃতিতে ঘোষিত হয় এবং আরম্ভ করা হয়; ভেরিয়েবলটি নাল, বা কোনও পদ্ধতি গোষ্ঠী বা বেনামে ফাংশন দিয়ে আরম্ভ করা যাবে না।
  2. ভের কীওয়ার্ড সংকলককে সূচনা করার স্টেটমেন্টের ডান পাশের এক্সপ্রেশন থেকে ভেরিয়েবলের ধরণ নির্ধারণের নির্দেশ দেয়।
  3. এটি বোঝা গুরুত্বপূর্ণ যে ভের্যাওয়ার্ডটির অর্থ "বৈকল্পিক" নয় এবং ভেরিয়েবলটি আলগাভাবে টাইপ করা হয়েছে বা দেরিতে-আবদ্ধ তা নির্দেশ করে না। এটির অর্থ কেবল যে সংকলক সর্বাধিক উপযুক্ত টাইপ নির্ধারণ করে এবং নির্ধারিত করে।

এমএসডিএন রেফারেন্স: সুস্পষ্টভাবে স্থানীয় ভেরিয়েবলগুলি টাইপ করা হয়েছে

বেনাম পদ্ধতি সম্পর্কে নিম্নলিখিত বিবেচনা করা:

  1. বেনামে পদ্ধতি আপনাকে পরামিতি তালিকা বাদ দিতে সক্ষম করে।

এমএসডিএন রেফারেন্স: নামবিহীন পদ্ধতি

আমি সন্দেহ করব যেহেতু বেনাম পদ্ধতিতে আসলে ভিন্ন পদ্ধতি স্বাক্ষর থাকতে পারে, তাই সংকলক সঠিকভাবে নির্ধারণ করতে অক্ষম যে সর্বাধিক উপযুক্ত টাইপটি কী হবে।


1

আমার পোস্টটি আসল প্রশ্নের উত্তর দেয় না, তবে এটি এর অন্তর্নিহিত প্রশ্নের উত্তর দেয়:

"আমি কীভাবে কিছু ধমক ধরণের টাইপ করা এড়াতে পারি Func<string, string, int, CustomInputType, bool, ReturnType>?" [1]

আমি যে অলস / হ্যাকি প্রোগ্রামার হয়েছি, তাই আমি এটি ব্যবহার করে পরীক্ষা-নিরীক্ষা করেছি Func<dynamic, object>- যা একটি একক ইনপুট প্যারামিটার নেয় এবং কোনও বস্তু ফেরত দেয়।

একাধিক যুক্তির জন্য, আপনি এটি এর মতো ব্যবহার করতে পারেন:

dynamic myParams = new ExpandoObject();
myParams.arg0 = "whatever";
myParams.arg1 = 3;
Func<dynamic, object> y = (dynObj) =>
{
    return dynObj.arg0.ToUpper() + (dynObj.arg1 * 45); //screw type casting, amirite?
};
Console.WriteLine(y(myParams));

টিপ: আপনার Action<dynamic>যদি কোনও জিনিস ফেরত দেওয়ার দরকার না হয় তবে আপনি ব্যবহার করতে পারেন ।

হ্যাঁ আমি জানি এটি সম্ভবত আপনার প্রোগ্রামিং নীতিগুলির বিপরীতে চলেছে, তবে এটি আমার এবং সম্ভবত কিছু পাইথন কোডারগুলি বোঝায়।

আমি প্রতিনিধিদের কাছে বেশ নবজাতক ... আমি যা শিখেছি তা কেবল ভাগ করে নিতে চেয়েছিলাম।


[1] এটি ধরে নিয়েছে যে আপনি এমন কোনও পদ্ধতির জন্য কল করছেন না যার জন্য Funcপরামিতি হিসাবে পূর্বনির্ধারিত প্রয়োজন , সেই ক্ষেত্রে আপনাকে সেই শিগ্র স্ট্রিংটি টাইপ করতে হবে: /


0

এটা কেমন?

var item = new
    {
        toolisn = 100,
        LangId = "ENG",
        toolPath = (Func<int, string, string>) delegate(int toolisn, string LangId)
        {
              var path = "/Content/Tool_" + toolisn + "_" + LangId + "/story.html";
              return File.Exists(Server.MapPath(path)) ? "<a style=\"vertical-align:super\" href=\"" + path + "\" target=\"_blank\">execute example</a> " : "";
        }
};

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