"এক্স নাল ইজ" এবং "এক্স == নাল" এর মধ্যে পার্থক্য কী?


277

সি # 7 এ আমরা ব্যবহার করতে পারি

if (x is null) return;

পরিবর্তে

if (x == null) return;

পুরানো উপায়ে নতুন উপায় (পূর্ববর্তী উদাহরণ) ব্যবহার করার কোনও সুবিধা আছে কি?

শব্দার্থবিজ্ঞান কি অন্যরকম?

শুধু স্বাদের জিনিস? যদি না হয়, আমি কখন অন্যটির ওপরে ব্যবহার করব?

তথ্যসূত্র: সি # 7.0 এ নতুন


4
এই লিঙ্কটি আমি কেবল দেখছিলাম, তবে এটি আপনাকে বেশি তথ্য দেয় না যার কারণেই আমি অনুমান করি যে ওপি প্রশ্ন জিজ্ঞাসা করছে। পৃষ্ঠার সর্বাধিক গুরুত্বপূর্ণ অংশটি হ'ল অপারেটরটি "হ'ল" অপারেটর কোনও অবজেক্টের রান-টাইম টাইপ কোনও প্রদত্ত টাইপের সাথে সামঞ্জস্যপূর্ণ কিনা তা পরীক্ষা করতে ব্যবহৃত হয়। অন্য কথায়, আমরা কোনও বস্তুর প্রকার যা প্রত্যাশা করে তা যাচাই করে তা পরীক্ষা করতে "হয়" অপারেটরটি ব্যবহার করি। আসুন এর বাক্য
সাইমন প্রাইস

2
@ সিমোনপ্রাইস এটি সি #: সি # of এর বর্তমান সংস্করণ সম্পর্কে This এই প্রশ্নটি সি # 7 সম্পর্কে, যা প্যাটার্নের মিল রয়েছে
প্যাট্রিক Hofman

@ বিগাউন আপনি কী ধরণের বিশদটি সন্ধান করছেন?
প্যাট্রিক হফম্যান

@ পেট্রিকহফম্যান এই জাতীয় ধরণের উত্তর দিয়েছেন, উদাহরণস্বরূপ
ম্যানেরো

উত্তর:


231

আপডেট: ওভারলোডেড সমতা অপারেটর না থাকাকালীন দুটি অপারেটরের আচরণ একই করার জন্য রোজলিন সংকলক আপডেট করা হয়েছে । দয়া করে বর্তমান সংকলক ফলাফলগুলিতে ( M1এবং M2কোডটিতে) কোডটি দেখুন যা কোনও ওভারলোডেড সমতার তুলনাকারী না থাকলে কী ঘটে তা দেখায়। তাদের উভয়েরই এখন আরও ভাল পারফরম্যান্সের ==আচরণ। যদি ওভারলোডেড সমতা তুলনামূলক হয় তবে কোডটি এখনও পৃথক

নীচের বিশ্লেষণটি রোজলিন সংকলনের পুরানো সংস্করণগুলির জন্য দেখুন।


কারণ nullসি # 6. এর সাথে আমরা যা অভ্যস্ত তা নিয়ে কোনও পার্থক্য নেই তবে যাইহোক, আপনি যখন nullঅন্য ধ্রুবকে পরিবর্তন করেন তখন বিষয়গুলি আকর্ষণীয় হয়ে ওঠে ।

উদাহরণস্বরূপ এটি নিন:

Test(1);

public void Test(object o)
{
    if (o is 1) Console.WriteLine("a");
    else Console.WriteLine("b");
}

পরীক্ষার ফলন হয় a। আপনি যদি o == (object)1এটি সাধারণভাবে যা লিখতেন তার সাথে যদি এটি তুলনা করেন, তবে এটি কোনও তাত্পর্য সৃষ্টি করে। isতুলনার অন্য দিকে ধরণ বিবেচনা করে। এটা চমৎকার!

আমি মনে করি == nullবনাম is nullধ্রুবক প্যাটার্নটি কেবল 'দুর্ঘটনা দ্বারা' খুব পরিচিত, যেখানে isঅপারেটরের বাক্য গঠন এবং সমতুল্য অপারেটর একই ফলাফল দেয়।


যেমন স্বিক মন্তব্য করেছেন, is nullকলSystem.Object::Equals(object, object)==ceq করেছেন যেখানে কল

আইএল এর জন্য is:

IL_0000: ldarg.1              // Load argument 1 onto the stack
IL_0001: ldnull               // Push a null reference on the stack
IL_0002: call bool [mscorlib]System.Object::Equals(object, object) // Call method indicated on the stack with arguments
IL_0007: ret                  // Return from method, possibly with a value

আইএল এর জন্য ==:

IL_0000: ldarg.1              // Load argument 1 onto the stack
IL_0001: ldnull               // Push a null reference on the stack
IL_0002: ceq                  // Push 1 (of type int32) if value1 equals value2, else push 0
IL_0004: ret                  // Return from method, possibly with a value

যেহেতু আমরা কথা বলছি null, কোনও পার্থক্য নেই যেহেতু এটি কেবল উদাহরণগুলিতে পৃথক করে । আপনি যখন সাম্যতা অপারেটরটি ওভারলোড করেছেন তখন এটি পরিবর্তন করতে পারে।


15
@ পেট্রিকহফম্যান এটি isকলগুলির মতো দেখায় object.Equals(x, null), যখন ==সংকলন করে ceqতবে ফলাফলটি একই হওয়া উচিত, যেমনটি আপনি বলেছেন।
নভিক

16
==ওভারলোডযোগ্য অপারেটর এটি সর্বদা মনে রাখবেন । এটির সাথে আপনার যে কোনও আচরণ থাকতে পারে। উদাহরণস্বরূপ, এই অদ্ভুতভাবে প্রয়োগ করা== আপনার অভ্যাসটি সত্যই নালার তা আপনাকে জানায় না। is nullঅন্যদিকে সবসময় সত্য নাল রেফারেন্স জন্য সত্য ফিরে আসবে :) উপরন্তু, আপনি আছে যদি ReferenceEqualsআপনার কোডে, বনাম 2017 আলোর বাল্ব পরিবর্তন করতে সুপারিশ করবে is null, না == null(সঠিকভাবে)।
নওফাল

2
@ পেট্রিকহফম্যান @ এসভিক দুটি নাল চেক এখন একই জিনিসটি সংকলন isকরেছেন , সুতরাং নাল পরীক্ষা করার জন্য যখন ব্যবহৃত হয় তখন কোনও ফাংশন কলের ওভারহেড থাকে না। প্রমাণের জন্য, মন্তব্যগুলিতে @ এসভিক পোস্ট করা লিঙ্কটি দেখুন।
AndreasHassing

1
@ AndreasBjørnHassingNielsen আমার উত্তর আপডেট করেছে।
প্যাট্রিক হফম্যান

2
@ পেট্রিকহফম্যানকে কি অন্যভাবে আইএল হওয়া উচিত নয়? == সিস্টেমকে কল করে b অবজেক্ট :: সমান (অবজেক্ট, অবজেক্ট) এবং একে নাল কল সিইএইচ
জিগিগিনউ লেডওউ

67

অতিরিক্ত লোড সমান অপারেটর

আপনি অপারেটরকে 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

এটি নির্দেশ করার জন্য ডেভিড অগস্টো ভিলাকে ধন্যবাদ ।


2
এ ছাড়াও, দ্রষ্টব্য (x নাল হয়) এর জন্য শ্রেণিক সীমাবদ্ধতার প্রয়োজন হয় যদি x একটি জেনেরিক ধরণের হয়, তবে (x == নাল) এবং অবজেক্ট R রেফারেন্সইকুয়ালস (x, নাল) না করে।
ডেভিড অগস্টো ভিলা
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.