2012-06-18 13 views
24

टाइप करने के लिए लागू नहीं किया जा सकता है, मुझे यह जानकर उत्सुकता है कि क्यों सी # कंपाइलर मुझे दूसरे कथन के लिए केवल एक त्रुटि संदेश देता है।ऑपरेटर ">" को 'ulong' और 'int'

enum Permissions : ulong 
{ 
    ViewListItems = 1L, 
} 

public void Method() 
{ 
    int mask = 138612833; 
    int compare = 32; 

    if (mask > 0 & (ulong)Permissions.ViewListItems > 32) 
    { 
     //Works 
    } 

    if (mask > 0 & (ulong)Permissions.ViewListItems > compare) 
    { 
     //Operator '>' cannot be applied to operands of type 'ulong' and 'int' 
    } 
} 
+1

इस त्रुटि का कारण स्पष्ट है। दूसरे उदाहरण में आप एक पूर्णांक के साथ एक अवैध संचालन करने की कोशिश कर रहे हैं। पहले उदाहरण में '32' को 'उलोंग' के रूप में माना जा रहा है। आपको वास्तव में 'मास्क' को 'उलंग' बनाना चाहिए। –

+0

@ रैमहाउंड या तो (''ulong'' की तुलना करें, या' 'const' चर 'की तुलना करें, इसलिए' const int तुलना = 32; '। लगातार अभिव्यक्तियों को स्वचालित रूप से 'int' से' ulong' में संकलित समय पर परिवर्तित कर दिया जाएगा यदि वे गैर-ऋणात्मक हैं, जो कुछ नाम _Iplplicit निरंतर अभिव्यक्ति रूपांतरण_ के नाम पर जाता है। –

उत्तर

30

मैं आउटपुट की जांच करने के लिए आईएलएसपी का उपयोग करके इसका प्रयोग कर रहा हूं, और यही वह है जो मैंने पाया है।

स्पष्ट रूप से आपके दूसरे मामले में यह एक त्रुटि है - आप ulong और int की तुलना नहीं कर सकते हैं क्योंकि ऐसा कोई प्रकार नहीं है जिससे आप दोनों को मजबूर कर सकें। long के लिए बहुत बड़ा हो सकता है, और int नकारात्मक हो सकता है।

हालांकि, आपके पहले मामले में, कंपाइलर चालाक हो रहा है। यह महसूस करता है कि 1> const 32 कभी भी सत्य नहीं है, और इसमें संकलित आउटपुट में if कथन शामिल नहीं है। (इसे पहुंचने योग्य कोड के लिए चेतावनी देना चाहिए।) यह वही है यदि आप शाब्दिक के बजाय const int को परिभाषित और उपयोग करते हैं, या यहां तक ​​कि यदि आप शाब्दिक रूप से शाब्दिक रूप से डाले हैं (यानी (int)32)।

लेकिन तब संकलक सफलतापूर्वक एक int है, जो हम सिर्फ इतना कहा असंभव था के साथ एक ulong की तुलना नहीं है?

स्पष्ट रूप से नहीं। तो पर जा रहा है?

निम्न पंक्तियों के साथ कुछ करने के बजाय प्रयास करें। (इनपुट ले रहा है और उत्पादन में लिख तो संकलक कुछ भी संकलन नहीं है दूर।)

const int thirtytwo = 32; 
static void Main(string[] args) 
{ 
    ulong x = ulong.Parse(Console.ReadLine()); 
    bool gt = x > thirtytwo; 
    Console.WriteLine(gt); 
} 

यह संकलन होगा, भले ही ulong एक चर रहा है, और भले ही परिणाम संकलन समय पर ज्ञात नहीं है। ILSpy में उत्पादन पर एक नज़र डालें:

private static void Main(string[] args) 
{ 
    ulong x = ulong.Parse(Console.ReadLine()); 
    bool gt = x > 32uL;  /* Oh look, a ulong. */ 
    Console.WriteLine(gt); 
} 

तो, संकलक अपने const int एक ulong के रूप में इलाज वास्तव में है। यदि आप thirtytwo = -1 बनाते हैं, तो कोड संकलित करने में विफल रहता है, भले ही हम जानते हैं कि gtहमेशा सत्य हो। संकलक स्वयं ulong की तुलना int से नहीं कर सकता।

यह भी ध्यान रखें कि यदि आप x एक ulong के बजाय एक long बनाने के लिए, संकलक 32L बजाय 32 उत्पन्न करता है एक पूर्णांक के रूप में, भले ही यह नहीं है के लिए करता है। क्योंकि यह को है संकलक पहले मामले में एक ulong रूप 32 इलाज नहीं करने के लिए

इस अंक (आप एक int और रनटाइम पर एक long तुलना कर सकते हैं।), केवल क्योंकि यह x के प्रकार के मिलान कर सकते हैं । यह निरंतर को मजबूर करने से रनटाइम को बचा रहा है, और यह केवल एक बोनस है जब अधिकारों द्वारा जबरदस्ती संभव नहीं होनी चाहिए।

+1

यह एक बहुत ही रोचक पढ़ा गया था, जो अनुसंधान के लिए आपके लिए प्रेरित है। – Amicable

+1

@Amicable - एक दिलचस्प सवाल के लिए _you_ के लिए props जो मुझे इसे शोध करना चाहता है :) – Rawling

+0

सी # कंपाइलर पूरी तरह से सी # भाषा विशिष्टता के साथ समझौते में है। जब 'int' प्रकार की अभिव्यक्ति संकलन-समय स्थिर होती है, तो वहां' int 'से एक [निहित निरंतर अभिव्यक्ति रूपांतरण] (http://msdn.microsoft.com/en-us/library/aa691286.aspx) मौजूद होता है। 'ulong' _provided है कि मान' ulong' की सीमा_ के भीतर है, यानी गैर-ऋणात्मक, जो सी # कंपाइलर निरंतर अभिव्यक्ति के साथ देख सकता है। '32' प्रकार 'int' की निरंतर अभिव्यक्ति है। जब टाइप 'int' की अभिव्यक्ति _not_ संकलित-समय स्थिर होती है, तो' ulong' के लिए कोई अंतर्निहित रूपांतरण मौजूद नहीं होता है। उदाहरण 'तुलना करें'। –

21

यह सीएलआर नहीं है यह त्रुटि संदेश यह संकलक है।

अपने पहले उदाहरण में संकलक व्यवहार करता है 32ulong (या एक प्रकार है कि परोक्ष ulong जैसे uint के लिए परिवर्तनीय है) अपने दूसरे उदाहरण में जबकि आप स्पष्ट रूप से एक के रूप में int प्रकार घोषित कर रखा है। > ऑपरेटर का कोई अधिभार नहीं है जो ulong और int स्वीकार करता है और इसलिए आपको एक कंपाइलर त्रुटि मिलती है।

+7

पूर्णांक अक्षर पृष्ठ (http://msdn.microsoft.com/en-us/library/aa664674.aspx) कहता है "यदि शाब्दिक में कोई प्रत्यय नहीं है, तो इसमें इन प्रकारों में से पहला है जिसमें इसका मूल्य प्रदर्शित किया जा सकता है: int, uint, long, ulong। " इसके अलावा मेरे इंटेलिसेंस (टूलटिप) का कहना है कि '32' एक 'int' है। लेकिन ऐसा लगता है कि क्या हो रहा है ... – Rawling

+1

@ राउलिंग बहुत सच है, मैं तीन संभावित कारण देख सकता हूं (मुझे डर है कि कई और हैं): # 1 शायद "मूल्य का प्रतिनिधित्व किया जा सकता है" की भिन्न व्याख्याओं के कारण, यानी संकलक जानता है कि 32 इंट नहीं हो सकता क्योंकि कोड संकलित नहीं होगा और आगे बढ़ने के बाद यूंट की कोशिश करता है। Intellisense स्पष्ट रूप से प्रकार की गणना करने के लिए पूरी अभिव्यक्ति का मूल्यांकन नहीं करता है, int आमतौर पर सही है तो क्यों एक किनारे के मामले के लिए कंप्यूटिंग समय बलिदान। # 2 पूर्णांक अक्षर के लिए प्रलेखन पुराना है। या # 3 यह एक कंपाइलर बग है। –

+0

@ राउलिंग - कोई बग नहीं है जो ठीक उसी तरह काम कर रहा है जैसा इसे करना चाहिए। शाब्दिक '32' को 'लम्बा' माना जा रहा है। आप कथन का भी उद्धरण देते हैं जहां यह कहता है कि इसे 'लंबा' माना जाएगा। –

3

rich.okelly और rawling के उत्तर सही हैं कि आप उनकी तुलना सीधे क्यों नहीं कर सकते हैं। Int को बढ़ावा देने के लिए आप Convert कक्षा ToUInt64 विधि का उपयोग कर सकते हैं।

if (mask > 0 & (ulong)Permissions.ViewListItems > Convert.ToUInt64(compare)) 
{ 
} 
संबंधित मुद्दे