2016-05-08 8 views
5

उदाहरण के लिए के साथ अपरिवर्तनीय प्रकार, मैं एक अपरिवर्तनीय प्रकारऑब्जेक्ट प्रारंभकर्ता वाक्य रचना

class Contact 
{ 
    // Read-only properties. 
    public string Name { get; } 
    public string Address { get; } 
} 

है और मुझे आशा है कि मैं एक संपर्क

Contact a = new Contact { Name = "John", Address = "23 Tennis RD" }; 

बनाने के लिए ऑब्जेक्ट प्रारंभकर्ता सिंटैक्स का उपयोग कर सकते हैं लेकिन मैं नहीं कर सकता। इस मामले में शक्तिशाली ऑब्जेक्ट प्रारंभकर्ता वाक्यविन्यास का उपयोग करने का कोई भी संभावित तरीका?

उत्तर

4

निकटतम बात वैकल्पिक पैरामीटर के साथ एक निर्माता होगा

new Contact(
    name: "John", 
    address: "23 Tennis RD" 
) 

वाक्य रचना एक ऑब्जेक्ट प्रारंभकर्ता से थोड़ा अलग है, लेकिन यह है बस पठनीय के रूप में; और आईएमओ, अंतर एक अच्छी बात है, क्योंकि कन्स्ट्रक्टर पैरामीटर अपरिवर्तनीय गुणों का सुझाव देते हैं। और आप किसी भी क्रम में पैरामीटर निर्दिष्ट कर सकते हैं, या कुछ बाहर छोड़ सकते हैं, तो यह ऑब्जेक्ट प्रारंभकर्ता वाक्यविन्यास जितना शक्तिशाली है।

इसके लिए कुछ अतिरिक्त कोड (कन्स्ट्रक्टर को परिभाषित करने, सभी गुणों को निर्दिष्ट करने) की आवश्यकता होती है, इसलिए यह ऑब्जेक्ट प्रारंभकर्ता वाक्यविन्यास से अधिक काम करता है। लेकिन बहुत भयानक नहीं है, और अपरिवर्तनीय वस्तुओं का मूल्य इसके लायक है।

(के लिए क्या इसके लायक है, सी # 7 immutable "record types" बहुत सरल वाक्य रचना है कि मिल सकता है ये या अंतिम रिलीज में आने से पहले हो सकता है नहीं है, लेकिन वे बहुत अच्छा ध्वनि।।)

0

ऑब्जेक्ट प्रारंभकर्ता पहले ऑब्जेक्ट का निर्माण करेगा, फिर संपत्ति मान सेट करेगा। इसे सेटर्स की आवश्यकता है।

Contact a = new Contact(); 
a.Name = "John"; 
a.Address = "23 Tennis RD"; 

एक केवल पढ़ने के क्षेत्र में यह एक बार वस्तु का निर्माण किया गया मान सेट नहीं हो सकता है:

यह कम हाथ के लिए है। उस वर्ग अपरिवर्तनीय करवाने के लिए, आप उन मूल्यों को लेने के लिए एक निर्माता बनाने की आवश्यकता होगी:

class Contact // Immutable class 
{ 
    // Read-only properties. 
    public string Name { get; } 
    public string Address { get; } 
    public Contact(string name, string address) 
    { 
     this.Name = name; 
     this.Address = address; 
    } 
} 
+0

मैं setters की जरूरत है - नहीं यह करता है नहीं! इसके लिए फ़ील्ड या प्रोपेरी पर लेखन पहुंच की आवश्यकता है। किसी संपत्ति के मामले में इसे वास्तव में एक सेटटर की आवश्यकता होती है। किसी क्षेत्र के मामले में यह स्थिर या पठनीय नहीं हो सकता है। –

+0

सही। कारण मैंने क्यों कहा: "फिर संपत्ति मूल्य निर्धारित करें, सेटटर की आवश्यकता है"। यहां तक ​​कि एक सार्वजनिक सेटर के साथ, यदि बैकिंग फ़ील्ड केवल पढ़ा गया था, तो इसे लिखने की कोशिश भी संकलित नहीं होगी। –

1

नहीं, आप केवल पढ़ने के लिए गुणों के साथ इसका इस्तेमाल नहीं कर सकते हैं।
यहां तुलना में विभिन्न संपत्ति और क्षेत्र के प्रकार हैं।

public class sometype { 
    public int readonlyProp{ 
     get; 
    } 
    public int normalProp { 
     get; 
     set; 
    } 

    public const int constField = 3; 
    public readonly int readonlyField = 3; 
    public int normalField = 3; 

    public void test() { 
     sometype test = new sometype() { readonlyProp = 3}; //  Doesn't work -> Property or indexer is readonly 
     sometype test1 = new sometype() { normalProp = 3 }; //  ok 
     sometype test2 = new sometype() { constField = 3 }; //  Doesn't work -> Static field or property 
     sometype test3 = new sometype() { readonlyField = 3 }; // Doesn't work -> readonly field 
     sometype test4 = new sometype() { normalField = 3 }; //  ok 
    } 
} 

यह समझना महत्वपूर्ण है कि कॉन्स्ट फ़ील्ड को स्थिर माना जाता है और इस प्रकार उदाहरण के सदस्य नहीं हैं। और चूंकि वस्तु प्रारंभकर्ता का उपयोग उदाहरण के सदस्यों के लिए किया जाता है, यह काम नहीं करता है।

class Contact 
{ 
    public string Name { get; } 
    public string Address { get; } 
    public Contact(string name = null, string address = null) { 
     Name = name; 
     Address = address; 
    } 
} 

तो फिर तुम यह पैरामीटर नाम के साथ कॉल कर सकते हैं:

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