2011-09-13 10 views
15

मैं एक भंडार क्लास और नीचे के रूप में एक सेवा वर्ग है:एक फ़ील्ड प्रारंभकर्ता गैर स्थैतिक फ़ील्ड, विधि या संपत्ति का संदर्भ नहीं दे सकता है?

public class DinnerRepository 
{ 
    DinnerDataContext db = new DinnerDataContext(); 

    public Dinner GetDinner(int id) 
    { 
     return db.Dinners.SingleOrDefault(d => d.DinnerID == id); 
    } 

// Others Code   
} 



public class Service 
{ 
     DinnerRepository repo = new DinnerRepository(); 
     Dinner dinner = repo.GetDinner(5); 

// Other Code 
} 

यह फेंकता त्रुटि:

A field initializer cannot reference the non-static field, method, or property.

हालांकि मैं DinnerRepository कक्षा intatiated है सेवा में अपनी विधि GetDinner() बेनकाब करने के लिए कक्षा। यह नीचे कोड के साथ ठीक काम करता है। क्या इसका कोई विकल्प है या क्या यह एक मानक अभ्यास है? मैं यहाँ स्थिर तरीकों का उपयोग नहीं कर सकते ..

public class Service 
{ 

    public Service() 
    { 
     DinnerRepository repo = new DinnerRepository(); 
     Dinner dinner = repo.GetDinner(5); 
    } 

} 

उत्तर

18

निजी तौर पर मैं सिर्फ खेतों एक निर्माता में प्रारंभ करेंगे:

public class Service 
{ 
    private readonly DinnerRepository repo; 
    private readonly Dinner dinner; 

    public Service() 
    { 
     repo = new DinnerRepository(); 
     dinner = repo.GetDinner(5); 
    } 
} 

ध्यान दें कि यह कोड आप नीचे दिखाने के समान नहीं है प्रश्न के रूप में, क्योंकि यह केवल स्थानीय चर घोषित कर रहा है। यदि आप केवल स्थानीय चर चाहते हैं, तो यह ठीक है - लेकिन अगर आपको उदाहरण चर की आवश्यकता है, तो ऊपर दिए गए कोड का उपयोग करें।

असल में, फ़ील्ड प्रारंभकर्ता सीमित हैं जो वे कर सकते हैं। सी # 4 कल्पना की धारा 10.5.5.2 से:

A variable initializer for an instance field cannot reference the instance being created. Thus it is a compile-time error to reference this in a variable initializer, because it is a compile-time error for a variable initializer to reference any instance member through a simple-name.

("इस प्रकार" और "इसलिए" गलत तरीके से गोल मेरे लिए लग रहा है यही कारण है कि - यह एक साधारण-नाम के माध्यम से एक सदस्य को संदर्भित करने के गैरकानूनी है क्योंकि यह संदर्भ this - मैं इसके बारे में मैड्स पिंग करेंगे -। लेकिन यह है कि मूल रूप से प्रासंगिक अनुभाग है)

+0

हाँ, वर्तमान संस्करण इस तरह पढ़ता है "चूंकि हमारे पास 'सरल नाम' पर एक संकलन समय त्रुटि है, हम 'यह' एक त्रुटि का संदर्भ देते हैं, और दूसरी तरफ नहीं। – SWeko

+0

@ जोनस्केट इस व्यवहार का कारण यह है कि क्षेत्र को कन्स्ट्रक्टर से पहले शुरू किया जाता है। इसलिए जब आप फ़ील्ड प्रारंभ करने का प्रयास करते हैं तो कोई इंस्टेंस सदस्य नहीं होता है। यही कारण है कि कक्षा को तुरंत चालू करने से पहले आप उनका उपयोग नहीं कर सकते हैं? – UfukSURMEN

+1

@UfukSURMEN: वास्तव में नहीं ... ऑब्जेक्ट पहले से मौजूद है, लेकिन यह कुछ सुंदर हार्ड-टू-कारण-बग के बारे में आमंत्रित करेगा। (कभी-कभी यह बहुत परेशान होता है, स्वीकार्य रूप से ...) –

2

यहां तक ​​कि अगर initializaton भाव "textual order" में होने की गारंटी दी जाती है, यह एक उदाहरण के लिए गैर कानूनी है initializers to access the this reference फ़ील्ड, और आप परोक्ष हैं इसे

में उपयोग करना

जो

Dinner dinner = this.repo.GetDinner(5); 

सबसे अच्छा अभ्यास IMHO के बराबर है, निरंतर मूल्यों करने के लिए या एक सरल new बयान के क्षेत्र initializations आरक्षण है। इससे कुछ भी हेयरियर एक कन्स्ट्रक्टर के पास जाना चाहिए।

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

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