2012-02-08 12 views
8

मेरे पास एक बड़ी स्थैतिक सूची है जो मूल रूप से एक लुकअप टेबल है, इसलिए मैं तालिका में तालिका शुरू करता हूं।कस्टम प्रकारों पर संग्रह प्रारंभकर्ता वाक्यविन्यास का उपयोग करना?

private class MyClass 
{ 
    private class LookupItem 
    { 
     public int Param1 { get; set; } 
     public int Param2 { get; set; } 
     public float Param2 { get; set; } 
     public float Param4 { get; set; } 
    } 

    private static List<LookupItem> _lookupTable = new List<LookupItem>() 
    { 
     new LookupItem() { Param1 = 1, Param2 = 2, Param3 = 3 Param4 = 4 }, 
     new LookupItem() { Param1 = 5, Param2 = 6, Param3 = 7 Param4 = 8 }, 
     //etc 
    } 
} 

असली LookupItem कई और अधिक गुण है, तो मैं एक निर्माता जोड़ा एक अधिक कॉम्पैक्ट initialisation प्रारूप के लिए अनुमति देने के लिए:

private class MyClass 
{ 
    private class LookupItem 
    { 
     public int Param1 { get; set; } 
     public int Param2 { get; set; } 
     public float Param2 { get; set; } 
     public float Param4 { get; set; } 

     public LookupItem(int param1, int param2, float param3, float param4) 
     { 
      Param1 = param1; 
      Param2 = param2; 
      Param3 = param3; 
      Param4 = param4;  
     } 
    } 

    private static List<LookupItem> _lookupTable = new List<LookupItem>() 
    { 
     new LookupItem(1, 2, 3, 4), 
     new LookupItem(5, 6, 7, 8), 
     //etc 
    } 
} 

क्या मैं सच में करना चाहते हैं प्रारूप initialiser संग्रह का उपयोग करें ऑब्जेक्ट के लिए ही मैं प्रत्येक पंक्ति पर new LookupItem() से छुटकारा पा सकता हूं। उदाहरण:

private static List<LookupItem> _lookupTable = new List<LookupItem>() 
{ 
    { 1, 2, 3, 4 }, 
    { 5, 6, 7, 8 }, 
    //etc 
} 

क्या यह संभव है? मुझे लगता है कि ऐसा इसलिए है क्योंकि KeyValuePairDictionary<> इस तरह से शुरू किया जा सकता है।

MSDN स्टेट्स:

संग्रह initializers जब आप एक संग्रह वर्ग कि IEnumerable लागू करता प्रारंभ आप एक या अधिक तत्व intializers स्पष्ट करने देते हैं। तत्व प्रारंभकर्ता एक साधारण मान, अभिव्यक्ति या ऑब्जेक्ट प्रारंभकर्ता हो सकते हैं। संग्रह प्रारंभकर्ता का उपयोग करके आपको अपने स्रोत कोड में कक्षा की जोड़ें विधि में एकाधिक कॉल निर्दिष्ट करने की आवश्यकता नहीं है; संकलक कॉल जोड़ता है।

क्या इसका मतलब है कि मुझे को LookupItem कक्षा पर लागू करने और प्रत्येक पैरामीटर को वापस करने की आवश्यकता है? मेरी कक्षा हालांकि संग्रह कक्षा नहीं है।

उत्तर

11

मुझे लगता है कि आपको सूची के बजाय कस्टम संग्रह करने की आवश्यकता है। इसे लुकअपइटेमटेबल कहें, उदाहरण के लिए। उस संग्रह को एक जोड़ें (int, int, float, float) विधि दें और इसे IENumerable लागू करें। उदाहरण के लिए:

class LookupItem 
{ 
    public int a; 
    public int b; 
    public float c; 
    public float d; 
} 

class LookupItemTable : List<LookupItem> 
{ 
    public void Add(int a, int b, float c, float d) 
    { 
     LookupItem item = new LookupItem(); 
     item.a = a; 
     item.b = b; 
     item.c = c; 
     item.d = d; 
     Add(item); 
    } 
} 

private static LookupItemTable _lookupTable = new LookupItemTable { 
    { 1, 2, 3, 4 }, 
    { 5, 6, 7, 8 } 
}; 

मैंने अब उपर्युक्त कोड की कोशिश की है और ऐसा लगता है कि यह मेरे लिए काम करता है।

+0

शानदार। आपका बहुत बहुत धन्यवाद। – GazTheDestroyer

4

आप अपने प्रकार पर नहीं, सूची पर ही एक संग्रह प्रारंभकर्ता उपयोग करने के लिए कोशिश कर रहे हैं:

// Note the "new List<...>" part - that specifies what type the collection 
// initializer looks at... 
private static List<LookupItem> _lookupTable = new List<LookupItem>() 
{ 
    { 1, 2, 3, 4 }, 
    { 5, 6, 7, 8 }, 
} 

तो यह List<T> पर चार मानकों के साथ एक Add विधि की तलाश में है, और जो मौजूद नहीं है।

कस्टम संग्रह प्रारंभकर्ता का उपयोग करने के लिए आपको अपने संग्रह कक्षा को लागू करना होगा। जबकि आप List<T> का उपयोग कर रहे हैं, तो आप जो कन्स्ट्रक्टर कॉल प्राप्त कर चुके हैं उसके साथ अटक गए हैं।

0

क्या इसका मतलब है कि मुझे अपने लुकअपइटम क्लास पर आईन्यूमेरेबल को लागू करने और प्रत्येक पैरामीटर को वापस करने की आवश्यकता है? मेरी कक्षा हालांकि संग्रह कक्षा नहीं है।

नहीं, यह मतलब है कि List<LookupItem> लागू करता IEnumerable, जिसके कारण आप

private static List<LookupItem> _lookupTable = new List<LookupItem>() 
{ 
    new LookupItem(1, 2, 3, 4), 
    new LookupItem(5, 6, 7, 8), 
    //etc 
} 

लिख सकते हैं इसका यह भी मतलब है कि यदि आपके LookupItem एक संग्रह है कि IEnumerable लागू किया था, तो आप लिख सकता:

private static List<LookupItem> _lookupTable = new List<LookupItem>() 
{ 
    new LookupItem { new Item(), new Item() }, 
    new LookupItem { new Item(), new Item() } 
} 
5

त्वरित फिक्स: अपना खुद का Listके साथ टाइप करेंअधिभार कि कई तथ्य होते हैं:

class LookupList : List<LookupItem> { 
    public void Add(int Param1, int Param2, ... sometype ParamX) { 
     this.Add(new LookupItem() { Param1 = Param1, Param2 = Param2, ... ParamX = ParamX }); 
    } 
} 

अब वास्तव में काम करता है के रूप में आप चाहते हैं:

private static LookupList _lookupTable = new LookupList() {     
     {1,2,3,4},     
     {2,7,6,3}     
    }; 

अधिक मौलिक जवाब:

आप object initializers और collection initializers अप मिश्रण कर रहे हैं। बस रखें:

ऑब्जेक्ट प्रारंभकर्ता एक वाक्य रचनात्मक चाल है कि पृष्ठभूमि में निर्दिष्ट नाम के साथ प्रत्येक नामित संपत्ति के लिए संपत्ति सेट विधियों को कॉल करें।

  • एक Array प्रकार के लिए: आइटम
  • किसी भी अन्य प्रकार के लिए, जो IEnumerable को लागू करना चाहिए के साथ सरणी भरें:

    संग्रह initializers एक वाक्यात्मक चाल है कि पृष्ठभूमि में हैं कॉल प्रत्येक उप-ब्रैकेट सेट के लिए Add विधि।

सभी है। उदाहरण के लिए निम्नलिखित हैक पर विचार करें:

public class Hack : IEnumerable { 
    public int LuckyNumber { get; set; } 
    public double Total { get; private set; } 
    public void Add(string message, int operand1, double operand2, double operand3) { 
     Console.WriteLine(message); 
     this.Total += operand1 * operand2 - operand3; 
    } 
    public IEnumerator GetEnumerator() { throw new NotImplementedException(); } 
} 

class Program { 
    static void Main(string[] args) { 
     Hack h1 = new Hack() { 
      { "Hello", 1, 3, 2}, 
      { "World", 2, 7, 2.9} 
     }; 
     Console.WriteLine(h1.Total); 
     Hack h2 = new Hack() { LuckyNumber = 42 }; 
     Console.WriteLine(h2.LuckyNumber); 
    } 
} 

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

+0

'आपको इसे वास्तविक कार्यक्रम में कभी नहीं करना चाहिए' - ठीक है। असली कार्यक्रम में आपको क्या करना चाहिए? परिदृश्य: जावा से पोर्टिंग, और एक कक्षा है जिसमें 3 'जोड़ें()' अधिभार है और लागू होता है 'IENumerable '। यदि मैं 'आईसीओलेक्शन ' लागू करता हूं, तो मेरे पास 'निकालें() ',' साफ़ करें() 'विधियों का एक समूह होगा जो मैं नहीं चाहता या आवश्यकता नहीं है। क्या इंटेलिसेंस का उपयोग करके संग्रह प्रारंभकर्ताओं का उपयोग करने के तरीके को और स्पष्ट करने के लिए कोई और समाधान है, या दस्तावेज लिखना मेरा एकमात्र विकल्प है? – NightOwl888

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