আমি একটি মাইক্রোসফ্ট সংযোগ নিবন্ধ সনাক্ত করতে সক্ষম হয়েছিল যা এই সমস্যাটি কিছুটা বিশদে আলোচনা করে:
দুর্ভাগ্যক্রমে, এই আচরণটি ডিজাইনের দ্বারা হয় এবং মান ধরণের ধরণের পরামিতিগুলির সাথে ব্যবহারের সক্ষম করার সহজ সমাধান নেই is
প্রকারগুলি যদি রেফারেন্সের ধরণের হিসাবে পরিচিত হয় তবে রেফারেন্সের সমতার জন্য অবজেক্ট টেস্টের চলকগুলিতে ডিফল্ট ওভারলোড বোঝানো হয়, যদিও কোনও প্রকার নিজস্ব কাস্টম ওভারলোড নির্দিষ্ট করতে পারে। সংকলক স্থিরপ্রাণ পরিবর্তনশীলের স্থিতিশীল প্রকারের ভিত্তিতে কোন ওভারলোডটি ব্যবহার করতে হবে তা নির্ধারণ করে (সংকল্পটি বহুকর্মী নয়)। অতএব, আপনি জেনেরিক প্রকারের প্যারামিটার টিটিকে সিলবিহীন রেফারেন্স টাইপের (যেমন ব্যতিক্রম হিসাবে) সীমাবদ্ধ করতে যদি আপনার উদাহরণ পরিবর্তন করেন তবে সংকলক নির্দিষ্ট ওভারলোডটি নির্দিষ্ট করতে পারে এবং নিম্নলিখিত কোডটি সংকলন করবে:
public class Test<T> where T : Exception
যদি প্রকারগুলি মান ধরণের হিসাবে পরিচিত হয় তবে ব্যবহৃত সঠিক ধরণের ভিত্তিতে নির্দিষ্ট মান সমতা পরীক্ষা করে। এখানে কোনও ভাল "ডিফল্ট" তুলনা নেই যেহেতু রেফারেন্স তুলনাগুলি মান ধরণের ক্ষেত্রে অর্থপূর্ণ নয় এবং সংকলকটি নির্ধারণ করতে পারে না যে কোন নির্দিষ্ট মানের তুলনা নির্গত হয়। সংকলকটি ValueType.Equals (অবজেক্ট) এ কল পাঠাতে পারে তবে এই পদ্ধতিটি প্রতিবিম্বটি ব্যবহার করে এবং নির্দিষ্ট মান তুলনার তুলনায় বেশ অকার্যকর। অতএব, আপনি যদি টি-তে কোনও মান-ধরণের সীমাবদ্ধতা নির্দিষ্ট করে থাকেন তবে কম্পাইলারের এখানে উত্পন্ন করার পক্ষে যুক্তিসঙ্গত কিছুই নেই:
public class Test<T> where T : struct
আপনি যে ক্ষেত্রে উপস্থাপন করেছেন সে ক্ষেত্রে, যেখানে সংকলকটি টি মান বা রেফারেন্স ধরণের কিনা তাও জানে না, একইভাবে উত্পন্ন করার মতো কিছুই নেই যা সমস্ত সম্ভাব্য ধরণের ক্ষেত্রে বৈধ হবে। কোনও রেফারেন্স তুলনা মান ধরণের জন্য বৈধ হবে না এবং কিছু ধরণের মান তুলনা অপ্রত্যাশিত এমন রেফারেন্স ধরণের জন্য যা ওভারলোড হয় না।
আপনি যা করতে পারেন তা এখানে ...
আমি বৈধতা দিয়েছি যে এই দুটি পদ্ধতিই রেফারেন্স এবং মান ধরণের জেনেরিক তুলনার জন্য কাজ করে:
object.Equals(param, default(T))
অথবা
EqualityComparer<T>.Default.Equals(param, default(T))
"==" অপারেটরের সাথে তুলনা করতে আপনাকে এই পদ্ধতির একটি ব্যবহার করতে হবে:
টি এর সমস্ত ক্ষেত্রে যদি জানা বেস ক্লাস থেকে নেওয়া হয় তবে আপনি জেনেরিক ধরণের বিধিনিষেধ ব্যবহার করে সংকলককে জানতে দিতে পারেন।
public void MyMethod<T>(T myArgument) where T : MyBase
সংকলকটি তখন কীভাবে অপারেশন করতে হবে তা সনাক্ত করে MyBase
এবং "অপারেটর '==' ফেলে দেবে না 'টি' এবং 'টি'" ত্রুটির টাইপের অপারেন্ডগুলিতে প্রয়োগ করা যাবে না যা আপনি এখন দেখছেন।
আরেকটি বিকল্প হ'ল টি প্রয়োগ করা হয় এমন যে কোনও ধরণের সীমাবদ্ধ IComparable
।
public void MyMethod<T>(T myArgument) where T : IComparable
এবং তারপরে আইকোম্যাপেবল ইন্টারফেসCompareTo
দ্বারা নির্ধারিত পদ্ধতিটি ব্যবহার করুন ।
if (myArgument?.Equals( default(T) ) != null )
।