C # में गलत ऑपरेटर के लिए क्या अच्छा है?


107

C # में दो अजीब ऑपरेटर हैं:

अगर मैं इस अधिकार को समझता हूं तो इन ऑपरेटरों का उपयोग उन प्रकारों में किया जा सकता है जो मैं बूलियन अभिव्यक्ति के बजाय उपयोग करना चाहता हूं और जहां मैं बूल को एक अंतर्निहित रूपांतरण प्रदान नहीं करना चाहता हूं।

मान लीजिए कि मेरे पास निम्न वर्ग है:

    public class MyType
    {
        public readonly int Value;

        public MyType(int value)
        {
            Value = value;
        }

        public static bool operator true (MyType mt)
        {
            return  mt.Value > 0;
        }

        public static bool operator false (MyType mt)
        {
            return  mt.Value < 0;
        }

    }

इसलिए मैं निम्नलिखित कोड लिख सकता हूं:

    MyType mTrue = new MyType(100);
    MyType mFalse = new MyType(-100);
    MyType mDontKnow = new MyType(0);

    if (mTrue)
    {
         // Do something.
    }

    while (mFalse)
    {
        // Do something else.
    }

    do
    {
        // Another code comes here.
    } while (mDontKnow)

हालाँकि सभी उदाहरणों के लिए केवल सच्चे ऑपरेटर को ही निष्पादित किया जाता है। तो सी # में झूठे ऑपरेटर के लिए क्या अच्छा है?

नोट: अधिक उदाहरण यहां , यहां और यहां देखे जा सकते हैं


आधुनिक डॉक्स dmic.microsoft.com/en-us/dotnet/csharp/language-reference/… पर देखे जा सकते हैं । डॉक्स सुझाव देते हैं कि इस ऑपरेटर को परिभाषित करने का कोई कारण नहीं है क्योंकि C # 2.0 ने अशक्त प्रकार जोड़े हैं।
मार्क अमेरी

जवाबों:


65

आप इसका उपयोग ऑपरेटर्स &&और ||ऑपरेटरों को ओवरराइड करने के लिए कर सकते हैं ।

&&और ||ऑपरेटरों ओवरराइड नहीं किया जा सकता है, लेकिन अगर आप को ओवरराइड |, &, trueऔर falseवास्तव में सही तरीके से संकलक कॉल करेंगे |और &आप लिखते हैं जब ||और &&

उदाहरण के लिए, इस कोड को देखें ( http://ayende.com/blog/1574/nhibernate-criteria-api-operator-overloading से - जहां मुझे इस ट्रिक के बारे में पता चला; @BiggsC द्वारा संग्रहीत संस्करण ):

public static AbstractCriterion operator &(AbstractCriterion lhs, AbstractCriterion rhs)
{
       return new AndExpression(lhs, rhs);
}

public static AbstractCriterion operator |(AbstractCriterion lhs, AbstractCriterion rhs)
{
       return new OrExpression(lhs, rhs);
}

public static bool operator false(AbstractCriterion criteria)
{
       return false;
}
public static bool operator true(AbstractCriterion criteria)
{
       return false;
}

यह स्पष्ट रूप से एक साइड इफेक्ट है और इसका उपयोग करने का इरादा नहीं है, लेकिन यह उपयोगी है।


आपका लिंक 404 है। यकीन नहीं होता कि आप इसे कैसे संपादित करना चाहते हैं, इसलिए मैंने इसे छोड़ दिया है।
user7116

मैंने एक संग्रहीत प्रतिलिपि के साथ URL को अपडेट किया ताकि इसे अभी भी पढ़ा जा सके।
IAmTimCorey

25

Shog9 और Nir: आपके उत्तर के लिए धन्यवाद। उन सवालों के जवाब मुझे की ओर इशारा किया स्टीव Eichert लेख और यह मेरे की ओर इशारा किया MSDN :

ऑपरेशन x && y का मूल्यांकन T.false (x) के रूप में किया जाता है? x: T। & (x, y), जहां T.false (x) T में घोषित ऑपरेटर का एक आह्वान है, और T। & (& x, y) चयनित ऑपरेटर और का एक आह्वान है। दूसरे शब्दों में, x का पहले मूल्यांकन किया जाता है और यदि गलत निश्चित रूप से x निश्चित रूप से गलत है, तो यह निर्धारित करने के लिए ऑपरेटर गलत है। फिर, यदि x निश्चित रूप से गलत है, तो ऑपरेशन का परिणाम x के लिए पहले गणना की गई वैल्यू है। अन्यथा, y का मूल्यांकन किया जाता है, और चयनित ऑपरेटर और x के लिए पहले से गणना किए गए मूल्य पर लागू किया जाता है और ऑपरेशन के परिणाम का उत्पादन करने के लिए y के लिए गणना की गई मूल्य।


मुझे आश्चर्य है कि उन्होंने (!T.true(x)) ? x : T.&(x, y)तर्क का उपयोग करने के लिए क्यों नहीं चुना है ।
डेस नेरगर

14

जिस पृष्ठ पर आप http://msdn.microsoft.com/en-us/library/6x6y6z4d.aspx से लिंक करते हैं, वे कहते हैं कि वे किस लिए थे, जो अशक्त मान प्रकारों को पेश करने से पहले अशक्त बस्तों को संभालने का एक तरीका था।

मुझे लगता है आजकल वे ArrayList जैसे सामान के लिए अच्छे हैं - यानी बिल्कुल कुछ भी नहीं।


7

AFAIK, इसका उपयोग झूठी के लिए एक परीक्षण में किया जाएगा, जैसे कि जब &&ऑपरेटर खेल में आता है। याद रखें, && शॉर्ट-सर्किट, इसलिए अभिव्यक्ति में

if ( mFalse && mTrue) 
{
   // ... something
}

mFalse.false()कहा जाता है, और trueअभिव्यक्ति लौटने पर 'mFalse.true ()' के लिए कॉल को कम कर दिया जाता है (जो तब वापस आ जाना चाहिए false, या चीजें अजीब हो जाएंगी)।

ध्यान दें कि &संकलित करने के लिए आपको उस अभिव्यक्ति के लिए ऑपरेटर को लागू करना होगा , क्योंकि इसका उपयोग यदि mFalse.false()रिटर्न होता है false


3

यह MSDN आलेख से प्रकट होता है जिसे आपने इससे जोड़ा था जो अशक्त बूलियन प्रकारों के लिए Null (यानी int ?, bool ?, आदि) से पहले टाइप करने के लिए C # 2 में भाषा में पेश किया जा रहा था। इस प्रकार आप एक आंतरिक मान दर्शाते हैं कि क्या मूल्य सही है या गलत या अशक्त है, अर्थात आपके उदाहरण में> 0 के लिए सत्य, <0 के लिए गलत और == 0 के लिए अशक्त है, और तब आपको SQL- शैली का शून्य शब्दार्थ मिलेगा। आपको एक .IsNull पद्धति या प्रॉपर्टी को भी लागू करना होगा ताकि शून्यता को स्पष्ट रूप से जांचा जा सके।

एसक्यूएल की तुलना में, मूल्य के साथ 3 पंक्तियों के साथ एक तालिका तालिका की कल्पना करें Foo सेट करने के लिए सही के साथ 3 पंक्तियाँ, मान के साथ 3 पंक्तियाँ झूठी पर सेट और 3 पंक्तियों के साथ मान Foo शून्य पर सेट है।

SELECT COUNT(*) FROM Table WHERE Foo = TRUE OR Foo = FALSE
6

सभी पंक्तियों को गिनने के लिए आपको निम्नलिखित कार्य करने होंगे: -

SELECT COUNT(*) FROM Table WHERE Foo = TRUE OR Foo = FALSE OR Foo IS NULL
9

इस 'IS NULL' वाक्य-विन्यास का आपकी कक्षा में समान कोड होगा .IsNull ()।

LINQ, C # को भी स्पष्ट करता है: -

int totalCount = (from s in MyTypeEnumerable
                 where s || !s
                 select s).Count();

कल्पना करना कि MyTypeEnumberable में डेटाबेस की समान सामग्री है, अर्थात 3 मान सत्य के बराबर, 3 मान मिथ्या के बराबर और 3 मान शून्य के बराबर। इस स्थिति में TotalCount इस मामले में 6 का मूल्यांकन करेगा। हालाँकि, अगर हमने कोड को फिर से लिखा है: -

int totalCount = (from s in MyTypeEnumerable
                 where s || !s || s.IsNull()
                 select s).Count();

तब TotalCount 9 का मूल्यांकन करेगा।

गलत ऑपरेटर पर लिंक किए गए MSDN आलेख में दिए गए DBNull उदाहरण BCL में एक वर्ग को प्रदर्शित करता है जिसके पास यह सटीक व्यवहार है।

वास्तव में निष्कर्ष यह है कि आपको इसका उपयोग नहीं करना चाहिए जब तक कि आप पूरी तरह से सुनिश्चित नहीं होते कि आप इस प्रकार का व्यवहार चाहते हैं, बेहतर है कि आप केवल सरल सरल अशक्त वाक्य रचना का उपयोग करें !!

अद्यतन: मैंने अभी देखा कि आपको लॉजिक ऑपरेटरों को मैन्युअल रूप से ओवरराइड करने की आवश्यकता है!, || और && इस कार्य को ठीक से करने के लिए। मेरा मानना ​​है कि झूठे ऑपरेटर इन तार्किक ऑपरेटरों को खिलाते हैं, अर्थात सत्य, झूठ या 'अन्यथा' का संकेत देते हैं। जैसा कि एक अन्य टिप्पणी में कहा गया है! X बल्ले से काम नहीं करेगा; आपको ओवरलोड करना होगा। Weirdness!

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.