2013-04-17 10 views
18

अधिकांश (यदि सभी नहीं) मेरी इकाई की रूपरेखा Pocos आभासी कार्य हैं। मुझे इन कार्यों को वर्चुअल होने की आवश्यकता है ताकि संस्था आलसी हो सकें।कन्स्ट्रक्टर में आभासी फ़ंक्शन को कॉल करने से कैसे बचें?

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

लेकिन यह कैसे मैं निर्माता में Accommodations प्रारंभ कर सकते हैं अगर नहीं?

public class Venue 
{ 
    public Venue() 
    { 
     Accommodations = new HashSet<Accommodation>(); 
    } 

    public virtual ICollection<Accommodation> Accommodations { get; set; } 
} 
+1

आलसी लोडिंग के बिंदु पर सभी यह प्रारंभ करने में, जब तक _not_ है पहला उपयोग। –

+0

@JohnWillemse अगर मैं यह शून्य जाने मैं मेरे विचार में अशक्त अपवाद मिल जाएगा। –

+0

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

उत्तर

12
public class Venue 
{ 
    private accommodations_ = new HashSet<Accommodation>(); 

    public Venue() { } 

    public virtual ICollection<Accommodation> Accommodations 
    { 
     get { return accommodations_; } 
     set { accommodations_ = value; } 
    } 
} 
+3

वह अजीब नामकरण सम्मेलन क्या है? आप आम तौर पर अंडरस्कोर को सामने रख देते हैं। –

+1

@ डैनियल हिल्गार्थ, मैं इसे बिल्कुल एक सम्मेलन नहीं कहूंगा - केवल मेरी (शायद खराब) आदत है कि मुझे वास्तव में बदलने की जरूरत है;) –

+0

ईएफ वैसे भी अग्रणी अंडरस्कोर पसंद नहीं करता है। – Casey

2

आलसी लोड हो रहा है के साथ, आप भी Accommodations तक यह पहली बार पहुँचा है प्रारंभ नहीं है, इसलिए यह null छोड़ दें।

आप के रूप में यह स्वत: ही प्रारंभ करने के लिए इस प्रकार लपेट कर सकते हैं:

private ICollection<Accommodation> _accommodations; 

public virtual ICollection<Accommodation> Accommodations { 
    get { 
     if (_accommodations == null) 
     { 
      // Initialize or load data here. 
      _accommodations = new HashSet<Accommodation>(); 
     } 
     return _accomodations; 
    } 
    set { 
     _accommodations = value; 
    } 
} 

इस समाधान के बारे में नीचे टिप्पणी पढ़ लें!

+7

वह ओआरएम के संदर्भ में आलसी लोडिंग के बारे में बात कर रहा है। ओआरएम आपके लिए यह सब ख्याल रखता है, इसलिए आपका उत्तर बिंदु को याद करता है। इसके अतिरिक्त, कृपया यहां दिखाए गए अभ्यास के बारे में [यह उत्तर] देखें (http://stackoverflow.com/questions/14774008/good-or-bad-practice-initializing-objects-in-getter/14774042#14774042)। –

+0

अच्छा बिंदु, हर दिन कुछ सीखो, जवाब में एक सूचक जोड़ा है। –

+0

लिंक डैनियल के लिए धन्यवाद। –

14

दूसरा विकल्प सेटटर को निजी के रूप में चिह्नित करना है। यह कन्स्ट्रक्टर में वर्चुअल सदस्यों को कॉल करने के मुद्दे से दूर हो जाएगा।

एक बार जब आप, आप कॉल करने के लिए तरीके (एफई के अलावा अन्य) के रूप में अपने डिजाइन के लिए आवश्यक है कि संपत्ति स्थापित करने के लिए उपलब्ध कराने की आवश्यकता है। आप पूरी तरह से समझाया लिए सुविधाएं मुहैया कराना की एक सूची में पारित करने के लिए एक ओवरलोड निर्माता का उपयोग कर सकते हैं, या वैकल्पिक रूप से आपके संग्रह (डोमेन संचालित डिजाइन) और उपयोग के तरीकों को संपुटित जोड़ने के लिए/(आइटम हटा टिप्पणी, एफई के साथ इस "hackish" हो जाता है, के रूप में यह समर्थन की कमी है संग्रह, NHibernate के साथ के विपरीत):

public class Venue 
{ 
    public Venue() 
    { 
     Accommodations = new HashSet<Accommodation>(); 
    } 

    public Venue(ICollection<Accommodation> accommodations) 
    { 
     Accommodations = new List<Accommodation>(accommodations); 
    } 

    public virtual ICollection<Accommodation> Accommodations { get; private set; } 
} 
+2

बिल्कुल वही जो मुझे चाहिए था। मजेदार है कि यह सवाल एक वर्ष से अधिक पुराना है, और फिर भी आप इसे देखने के करीब 4 घंटे पहले ही जवाब दे रहे हैं! – Xcelled194

0
सी # 6.0 डिफ़ॉल्ट प्रारंभ के साथ

यह निजी चर के उपयोग के बिना सरल किया जा सकता है:

public class Venue 
{ 
    public virtual ICollection<Accommodation> Accommodations {get; set; } = new HashSet<Accommodation>(); 
} 
संबंधित मुद्दे