2012-09-13 12 views
11

मैं यह जांचना चाहता हूं कि रन चर पर प्रोग्राम चरम पर प्रारंभ किया गया है या नहीं। इस कम रहस्यमय के कारणों को बनाने के लिए, कृपया निम्नलिखित अपूर्ण कोड देखें:सी # - जांच कर रहा है कि कोई वैरिएबल प्रारंभ किया गया है

string s; 

if (someCondition) s = someValue; 
if (someOtherCondition) s = someOtherValue; 

bool sIsUninitialized = /* assign value correctly */; 

if (!sIsUninitialized) Console.WriteLine(s) else throw new Exception("Please initialize s."); 

और प्रासंगिक बिट को पूरा करें।

string s = "zanzibar"; 

और फिर जाँच करता है, तो इसे बदल:

एक hacky समाधान एक डिफ़ॉल्ट मान के साथ प्रारंभ करने में है

bool sIsUninitialized = s == "zanzibar"; 
हालांकि

, क्या हुआ अगर someValue या someOtherValue "जंजीबार" होने के लिए होता है भी? तब मेरे पास एक बग है। कोई बेहतर तरीका?

+5

'string.IsNullOrEmpty (ओं)' – Shmiddty

+7

यह वास्तव में संकलित भी नहीं होगा। चर शुरू किया जाना है। बस इसे शून्य या स्ट्रिंग में प्रारंभ करें। लक्षण। – McGarnagle

+0

क्या होगा यदि चर किसी अन्य थ्रेड द्वारा प्रारंभ किया गया है? क्या आप लेखन पहुंच पर अपवाद उत्पन्न करने के लिए मेमोरी कंट्रोलर सेट अप करने में सहज हैं? – HABO

उत्तर

12

कोड संकलित भी नहीं करेगा यदि संकलक एक वैरिएबल जानता है प्रारंभ नहीं किया गया है।

string s; 
if (condition) s = "test"; 
// compiler error here: use of unassigned local variable 's' 
if (s == null) Console.Writeline("uninitialized"); 

अन्य मामलों में आप default कीवर्ड इस्तेमाल कर सकते हैं अगर एक चर प्रारंभ नहीं किया गया है। उदाहरण के लिए, निम्नलिखित मामले में:

class X 
{ 
    private string s; 
    public void Y() 
    { 
     Console.WriteLine(s == default(string)); // this evaluates to true 
    } 
} 

documentation राज्यों डिफ़ॉल्ट (टी) संदर्भ प्रकार के लिए null, और 0 मूल्य प्रकार के लिए दे देंगे कि। तो टिप्पणियों में बताया गया है, यह वास्तव में शून्य के लिए जांच के समान ही है।


यह सब तथ्य यह है कि क्या तुम सच में चर, null या जो कुछ भी, जब वे पहली बार घोषणा की जाती है को प्रारंभ करना चाहिए धुंधला कर देता है।

string s = null; 
bool init = false; 
if (conditionOne) { 
    s = someValueOne; 
    init = true; 
} 
if (conditionTwo) { 
    s = someValueTwo; 
    init = true; 
} 
if (!init) { 
    ... 
} 

यह उन परिस्थितियों का ध्यान जब s असाइन किया गया है ले जाएगा, जब यह null असाइन किया गया है, खाली स्ट्रिंग मामलों सहित, या:

+4

's == डिफ़ॉल्ट (स्ट्रिंग)' '== null' कहने का एक शानदार तरीका नहीं है? – dasblinkenlight

+1

@dasblinkenlight अच्छी तरह से हाँ, मूल रूप से, लेकिन मुझे लगता है कि यह इरादा थोड़ा और स्पष्ट बनाता है। – McGarnagle

+10

@dbaseman, मैं असहमत हूं। यह 'शून्य' के लिए क्या अच्छी तरह से ज्ञात समझ को obfuscates। –

2

आप एक अलग झंडा इंगित करता है कि स्ट्रिंग प्रारंभ कर दिया गया है रख सकते "zanzibar"

एक और समाधान "अनियमित" मान को इंगित करने के लिए एक स्थिर स्ट्रिंग बनाना है, और == के बजाय Object.ReferenceEquals का उपयोग यह जांचने के लिए करें कि यह बदल गया है या नहीं। हालांकि, bool परिवर्तनीय दृष्टिकोण आपके इरादे को और अधिक स्पष्ट रूप से व्यक्त करता है।

+0

फ्लैग का परिचय क्यों दें और न सिर्फ 'शून्य' के विरुद्ध तुलना करें? –

+5

@ किर्कवॉल यह एक अच्छा सवाल है, हालांकि मैंने जवाब में इसका जवाब देने का प्रयास किया: क्योंकि 'कुछ वैल्यूओ' या 'कुछ वैल्यू दो' वैध रूप से 'शून्य' हो सकता है। (अद्यतन: स्पष्ट रूप से, ओपी परवाह नहीं है :) – dasblinkenlight

+0

पर्याप्त मेला, मैंने आपके उत्तर को पर्याप्त रूप से पर्याप्त नहीं पढ़ा। ;) –

0

मैं प्रारंभिक मानों को चुनता हूं जिनका उपयोग कभी नहीं किया जा सकता है, विशिष्ट मानों में String.Empty, null, -1, और 256 वर्ण यादृच्छिक स्ट्रिंग जेनरेटर शामिल हैं।

+2

'string.Empty' =' "" ''। तीन गुना अधिक वर्बोज़ विकल्प का उपयोग करने की आवश्यकता नहीं है। आखिरकार, हम 'Int32.Zero' जैसी चीजों का उपयोग नहीं करते हैं। –

+0

मैं स्ट्रिंग पसंद करता हूं। लक्षण क्योंकि इसे '' 'से भ्रमित नहीं किया जा सकता है। मेरे लिए पढ़ना आसान है। –

+2

आपको '" "से भ्रमित नहीं किया जाना चाहिए। वास्तव में। यह किसी भी प्रोग्रामिंग भाषा का एक अभिन्न अंग है। –

3

बस इसे null डिफ़ॉल्ट रूप से असाइन करते हैं, नहीं एक स्ट्रिंग मान

+0

क्या होगा यदि 'शून्य' उस स्ट्रिंग के लिए 'if' कथन में से एक में असाइन किया गया मान्य मान है? – Servy

+0

@ सर्वी फिर एक निरंतर परिभाषित करें जो आपके गैर-शून्य, अनियमित मूल्य का प्रतिनिधित्व करता है, उदा। 'कॉन्स स्ट्रिंग UninitializedString = "ज़ांज़ीबार"; ' –

+1

@ पीटर गलक फिर यह स्थिर मान अब" अमान्य "हो जाता है, और इससे भी बदतर, यह असाधारण रूप से डीबगिंग को मुश्किल बना देगा क्योंकि अगर कुछ विधि बस यह वापस करने के लिए होती है कि यह क्यों नहीं चल रहा है सिरदर्द के सभी प्रकार का कारण बन जाएगा। – Servy

8

के साथ सी # 2.0, आप Nullable ऑपरेटर के रूप में ऐसी बातों के लिए अनुमति देता है, तो आप पहले मूल्य प्रकार के लिए अशक्त की एक प्रारंभिक मूल्य निर्धारित करने की अनुमति देता है:

int? x = null; 

if (x.HasValue) 
{ 
    Console.WriteLine("Value for x: " + num.Value); 
} 

कौन सा उपज: "एक्स: शून्य के लिए मूल्य"।,

string s; 
if (someCondition) { s = someValue; } 
else if (someOtherCondition) { s = someOtherValue; } 
else { throw new Exception("Please initialize s."); } 

Console.WriteLine(s) 

यह पता चल सके कि स्ट्रिंग शून्य है के लिए बेहतर हो सकता है क्योंकि शायद someValue एक विधि है कि कभी कभी अशक्त लौट सकते है:

+2

यह तारों पर लागू नहीं है, क्योंकि यह पहले से ही एक संदर्भ प्रकार है। – dasblinkenlight

+0

ओपी की प्रारंभिक वाक्य में कहा गया है, "मैं जांचना चाहता हूं कि रन टाइम पर एक चर प्रारंभ किया गया है या नहीं।" यह प्रकार केवल एक स्ट्रिंग था जिसे ओपी ने कहा था कि उसका उदाहरण "अपूर्ण कोड" था। –

+2

चेक में बूलियन अक्षर का उपयोग न करें, 'अगर (x.HasValue) लिखें'। बूलियन अक्षर प्रारंभिकरणों में केवल अर्थपूर्ण होते हैं (या पैरामीटर के रूप में पारित होने पर) - कहीं और नहीं। –

3

यहाँ एक तरीका है। दूसरे शब्दों में, स्ट्रिंग को प्रारंभ करने के लिए शायद शून्य एक वैध मान है।

व्यक्तिगत रूप से मुझे यह isInitialized ध्वज से बेहतर पसंद है। जब तक आपको कोई अतिरिक्त फ्लैग वैरिएबल पेश नहीं करना चाहिए? मुझे नहीं लगता कि यह अधिक पठनीय है।

+0

स्पष्ट रूप से 'कुछ वैल्यू' एक विधि नहीं है या यह 'कुछ वैल्यू()' होगा, लेकिन मेरा मतलब है "वास्तविक (गैर-सरलीकृत) मामले में"। यह अभी भी किसी भी दर पर 'शून्य 'हो सकता है। –

-1

सामान्य रूप से, null या String.Empty होने के लिए डिफ़ॉल्ट असाइन करें।

const string UninitializedString = "zanzibar"; 

फिर उस मूल्य को संदर्भित जब भी आप प्रारंभ या आरंभीकरण के लिए परीक्षण करना चाहते हैं:

string foo = UnininitializedString; 
if (foo == UninitiaizedString) { 
    // Do something 
} 
स्थितियों में, जहां आप उन "खाली" मूल्यों का उपयोग नहीं कर सकते हैं के लिए, अपना एप्लिकेशन-विशिष्ट अप्रारंभीकृत मूल्य का प्रतिनिधित्व करने के लिए एक निरंतर परिभाषित

याद रखें कि तार सी # में अपरिवर्तनीय स्थिरांक हैं इसलिए UninitializedString का वास्तव में केवल एक उदाहरण है (यही कारण है कि तुलना काम करता है)।

+1

यह आपदा के लिए एक नुस्खा है। किसी बिंदु पर आप उस "अनियमित" मूल्य के लिए वैध असाइनमेंट के साथ समाप्त हो सकते हैं, जिससे प्रोग्रामर के लिए भ्रम के सभी प्रकार होते हैं जिन्हें यह निर्धारित करने की आवश्यकता होती है कि यह क्यों काम नहीं कर रहा है। – Servy

+0

@ सर्वी ऐसा नहीं है। यही कारण है कि आप पूरे कोड में "नग्न" स्ट्रिंग को छिड़कने के बजाय नामित स्थिर का उपयोग करते हैं। सड़क के नीचे आवश्यकतानुसार निरंतर बदला जा सकता है। और ध्यान दें कि मैंने कहा था कि आपकी पहली पसंद 'शून्य' या 'स्ट्रिंग। लक्षण' का उपयोग करना है। वास्तव में, 'कॉन्स स्ट्रिंग UninitializedString = स्ट्रिंग। लक्षण;' मेरी पहली पसंद होगी। –

+1

आप पहली बार कोड में "नग्न" स्ट्रिंग को कभी भी छिड़कते नहीं हैं। आप [इस एक] जैसे समाधान का उपयोग करते हैं (http://stackoverflow.com/a/12414058/1159478) जो "अनियमित मूल्य" का प्रतिनिधित्व करने के लिए कभी भी किसी भी मान का उपयोग नहीं करता है। कि आप इसे बदल सकते हैं (संकलन समय पर) यहां खतरों को भी कम नहीं करता है। यदि स्ट्रिंग उपयोगकर्ता इनपुट पर आधारित हो सकती है तो आपको समय संकलित करने का कोई विचार नहीं है कि उपयोगकर्ता क्या चुन सकता है; कोई फर्क नहीं पड़ता कि आप क्या चुनते हैं यह गलत हो सकता है। वास्तव में यह असामान्य नहीं है कि असामान्य असाइनमेंट 'शून्य' या खाली स्ट्रिंग के लिए असामान्य है, इसलिए इसका उपयोग करने से कोई मदद नहीं मिलेगी। – Servy

संबंधित मुद्दे