অতিরিক্ত লোড সমান অপারেটর
আপনি অপারেটরকে nullওভারলোড করে এমন কোনও প্রকারের সাথে তুলনা করার সময় দুটি তুলনার মধ্যে শব্দার্থতত্ত্বের মধ্যে আসলেই পার্থক্য রয়েছে ==। foo is nullফলাফল নির্ধারণের জন্য প্রত্যক্ষ রেফারেন্স তুলনা ব্যবহার করবে, অন্যদিকে foo == nullঅবশ্যই ==যদি এটি বিদ্যমান থাকে তবে ওভারলোডেড অপারেটরটি চালাবে ।
এই উদাহরণে আমি ওভারলোডেড ==অপারেটরে একটি "বাগ" প্রবর্তন করেছি , যার ফলে দ্বিতীয় যুক্তিটি থাকলে এটি সর্বদা ব্যতিক্রম হয় null:
void Main()
{
Foo foo = null;
if (foo is null) Console.WriteLine("foo is null"); // This condition is met
if (foo == null) Console.WriteLine("foo == null"); // This will throw an exception
}
public class Foo
{
public static bool operator ==(Foo foo1, Foo foo2)
{
if (object.Equals(foo2, null)) throw new Exception("oops");
return object.Equals(foo1, foo2);
}
// ...
}
সরাসরি রেফারেন্স তুলনা সম্পাদনের foo is nullজন্য ceqনির্দেশ ব্যবহার করে আইএল কোড :
IL_0003: ldloc.0 // foo
IL_0004: ldnull
IL_0005: ceq
foo == nullওভারলোড হওয়া অপারেটরের কাছে একটি কল ব্যবহার করার জন্য আইএল কোড :
IL_0016: ldloc.0 // foo
IL_0017: ldnull
IL_0018: call UserQuery+Foo.op_Equality
সুতরাং পার্থক্যটি হ'ল, আপনি যদি ব্যবহার করেন তবে ==ব্যবহারকারীর কোডটি চালনার ঝুঁকি রয়েছে (যার সম্ভাব্য অপ্রত্যাশিত আচরণ বা পারফরম্যান্স সমস্যা হতে পারে)।
জেনেরিকের উপর সীমাবদ্ধতা
is nullকনস্ট্রাক্ট ব্যবহার করা টাইপটিকে একটি রেফারেন্স টাইপের মধ্যে সীমাবদ্ধ করে। সংকলক এটি নিশ্চিত করে, যার অর্থ আপনি is nullকোনও মান ধরণের ক্ষেত্রে ব্যবহার করতে পারবেন না । আপনার যদি জেনেরিক পদ্ধতি থাকে is nullতবে জেনেরিক প্রকারটি রেফারেন্স ধরণের হিসাবে সীমাবদ্ধ না করা পর্যন্ত আপনি ব্যবহার করতে পারবেন না ।
bool IsNull<T>(T item) => item is null; // Compile error: CS0403
bool IsNull<T>(T item) => item == null; // Works
bool IsNull<T>(T item) where T : class => item is null; // Works
এটি নির্দেশ করার জন্য ডেভিড অগস্টো ভিলাকে ধন্যবাদ ।