6

क्या सी # में एक विशेषता संग्रह प्रारंभकर्ता के साथ उपयोग की जा सकती है?क्या मैं एक विशेषता के लिए संग्रह प्रारंभकर्ता का उपयोग कर सकता हूं?

उदाहरण के लिए, मैं निम्नलिखित की तरह कुछ करने के लिए करना चाहते हैं:

[DictionaryAttribute(){{"Key", "Value"}, {"Key", "Value"}}] 
public class Foo { ... } 

मैं गुण पैरामीटर नाम दिया जा सकता है, और के बाद से है कि initializers आपत्ति उठाने का बहुत समान लगता है, मैं अगर संग्रह initializers थे सोच रहा था पता साथ ही उपलब्ध है।

+0

स्कॉट, मुझे खेद है - मेरा जवाब असफल रहा है। मैं वोट अर्जित नहीं करता हूं। कृपया अपने निष्पक्ष खेल को वोट दें। – vladimir77

+0

@ vladimir77 - आपको अपना जवाब नहीं हटाया जाना चाहिए था! कभी-कभी गलत उत्तर अभी भी सहायक होता है ... अगली बार अपने उत्तर को अपडेट करें, ताकि लोग समझ सकें कि यह गलत क्यों है। –

+0

ठीक है। :) Ive इसे बहाल करें। – vladimir77

उत्तर

6

अपडेट : मैं माफी चाहता मैं गलत कर रहा हूँ कर रहा हूँ - कस्टम प्रकार की सरणी पारित असंभव :(

एक विशेषता वर्ग के लिए स्थितीय और नाम वाले पैरामीटर के प्रकार विशेषता पैरामीटर प्रकार, जो कर रहे हैं करने के लिए सीमित कर रहे हैं:

  1. निम्नलिखित प्रकार से एक: bool, बाइट, चार, डबल, नाव, पूर्णांक, लंबे, लघु, स्ट्रिंग
  2. टाइप ऑब्जेक्ट।
  3. प्रकार सिस्टम टाइप करें। टाइप करें।
  4. एक एनम प्रकार, बशर्ते इसमें सार्वजनिक पहुंच हो और टाइप करें जिसमें इसे नेस्टेड किया गया है (यदि कोई है) में सार्वजनिक पहुंच भी है (धारा 17.2)।
  5. के प्रकारों के एकल-आयामी सरणी। source

स्रोत: stackoverflow

आप एक कस्टम प्रकार की एक सरणी गुजर घोषणा कर सकते हैं:

[Test(new[]{new TestType(1, "1"), new TestType(2, "2"), })] 
public void Test() 
{ 

} 
+0

चूंकि आपके पास 'पैरा' है, इसलिए आप बहुत अच्छे सिंटैक्स के लिए 'नया [] {...} 'छोड़ सकते हैं। हालांकि, क्या आप वाकई संकलित हैं? मुझे लगता है कि विशेषता तर्कों में सीमाएं हैं - निरंतर अभिव्यक्ति, टाइपोफ अभिव्यक्ति, या सरणी निर्माण अभिव्यक्ति - जैसा कि @ जेसन डाउन द्वारा उल्लेख किया गया था। –

+1

@ स्कॉट: वह _is_ एक सरणी निर्माण अभिव्यक्ति है। :) (वैसे, मैं अपना जवाब हटा दूंगा; जैसा कि जेसन ने बताया कि यह अच्छा नहीं है।) –

+0

मुझे खेद है कि मैं असफल रहा :( – vladimir77

3

संक्षिप्त उत्तर नहीं है।

लंबा उत्तर: संग्रह प्रारंभकर्ताओं का समर्थन करने के लिए कक्षा के लिए, इसे IENumerable को लागू करने की आवश्यकता है और इसे एक अतिरिक्त विधि की आवश्यकता है। उदाहरण के लिए:

public class MyClass<T,U> : IEnumerable<T> 
{ 
    public void Add(T t, U u) 
    { 
    } 

    public IEnumerator<T> GetEnumerator() 
    { 
     throw new NotImplementedException(); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 
} 

मैं तो ऐसा कर सकते हैं:

var mc = new MyClass<int, string> {{1, ""}, {2, ""}}; 

तो इस का उपयोग करते हुए, चलो यह एक विशेषता के लिए काम करने के लिए कोशिश करते हैं।

public class CollectionInitAttribute : Attribute, IEnumerable<string> 
{ 
    public void Add(string s1, string s2) 
    { 

    } 

    public IEnumerator<string> GetEnumerator() 
    { 
     throw new NotImplementedException(); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 
} 

और अब यह परीक्षण करने के लिए: (पक्ष टिप्पणी के बाद से गुण जेनरिक का समर्थन नहीं करते, मैं सिर्फ यह परीक्षण के लिए तार का उपयोग कर हार्डकोड कर रहा हूँ)

[CollectionInit{{"1","1"}}] 
public class MyClass 
{ 

} 

और उस संकलन नहीं है :(मुझे यकीन नहीं है कि सीमा वास्तव में कहां है, मैं अनुमान लगा रहा हूं कि एक नियमित वस्तु है और इसलिए यह समर्थित नहीं है। इसलिए यह उत्सुक होगा अगर यह सैद्धांतिक रूप से समर्थित हो भाषा का भविष्य का संस्करण ....

+0

आपके संक्षिप्त उत्तर और आपके लंबे समय के लिए धन्यवाद! यही वही है जो मैंने कोशिश की, लेकिन जब यह संकलित नहीं हुआ, तो मुझे यकीन नहीं था कि यह एक दोषपूर्ण वाक्यविन्यास या असमर्थित सुविधा थी। मुझे यह भी नहीं पता था कि जेनेरिकों की अनुमति नहीं थी। –

+0

एफवाईआई मुझे आपका जवाब बहुत पसंद है, लेकिन मैंने @ vladimir77 के जवाब को स्वीकार करने का फैसला किया क्योंकि इसका एमएसडीएन से उद्धृत एक निश्चित उत्तर है, और यह सवाल के लिए सबसे अच्छा जवाब प्रतीत होता है। –

+0

@ स्कॉट: कोई बड़ा सौदा नहीं। मैं सिर्फ यह इंगित करना चाहता हूं कि यह नामित पैरामीटर का मुद्दा नहीं है, क्योंकि यह वह नहीं है जिसे आप करने का प्रयास कर रहे थे। आप संग्रह intializer वाक्यविन्यास का उपयोग करने की कोशिश कर रहे थे, जो एक अलग चीज है ... – BFree

5

धारा सी # 4.0 विनिर्देश के 17.1.3 विशेष रूप से नहीं करता है: विशेषता घोषणा पर

class TestType 
{ 
    public int Id { get; set; } 
    public string Value { get; set; } 

    public TestType(int id, string value) 
    { 
    Id = id; 
    Value = value; 
    } 
} 

class TestAttribute : Attribute 
{ 
    public TestAttribute(params TestType[] array) 
    { 
    // 
    } 
} 

लेकिन संकलन त्रुटियां होती हैं विशेषता पैरामीटर के अंदर बहुआयामी सरणी की अनुमति दें, इसलिए जब फू (स्ट्रिंग [,] बार) आपको Foo (नया [,] {{"a", "b"}, {"key2", "val2"} कॉल करने की अनुमति दे सकता है }), दुर्भाग्य से, विशेषताओं के लिए उपलब्ध नहीं है।

तो यह है कि मन में साथ, कुछ संभावनाएं अनुमान लगाने के लिए क्या आप चाहते हैं कर रहे हैं:

  1. उपयोग एक एकल आयामी सरणी, कुंजी और मान जोड़े बारी के साथ। इस दृष्टिकोण के स्पष्ट नकारात्मक पक्ष यह है कि यह वास्तव में नामों और मूल्यों को लागू नहीं कर रहा है।

  2. अपने पैरामीटर निम्न विशेषता के साथ अपने गुण परिभाषा टैग करके कई बार प्रकट करने के लिए अनुमति दें:

    [AttributeUsage(AllowMultiple=true)] 
    

    इस तरह, आप अब परिभाषित कर सकते हैं:

    [KeyVal("key1","val1"), KeyVal("key2","val2")] 
    public class Foo { ... } 
    

    इसमें कुछ समय wordier है मुझे यकीन है कि आप उम्मीद कर रहे थे, लेकिन यह नाम और मूल्यों के बीच एक स्पष्ट चित्रण बनाता है।

  3. एक JSON पैकेज ढूंढें और अपनी विशेषता के लिए प्रारंभकर्ता प्रदान करें। प्रदर्शन हिट अपरिहार्य है क्योंकि यह कोड प्रारंभिकरण के दौरान किया जाता है। का उपयोग करते हुए Newtonsoft.Json, उदाहरण के लिए, यदि आप ऐसा तरह एक विशेषता बना सकता है:

    public class JsonAttribute : Attribute 
        { 
         Dictionary<string, string> _nameValues = 
          new Dictionary<string, string>(); 
         public JsonAttribute(string jsoninit) 
         { 
         var dictionary = new Dictionary<string, string>(); 
         dynamic obj = JsonConvert.DeserializeObject(jsoninit); 
         foreach(var item in obj) 
          _nameValues[item.Name] = item.Value.Value; 
         } 
        } 
    

    कौन सा तो तुम इतनी तरह एक विशेषता का दृष्टांत करने की अनुमति होगी:

    [Json(@"{""key1"":""val1"", ""key2"":""val2""}")] 
    public class Foo { ... } 
    

    मैं जानता हूँ कि यह एक छोटे है बोली-खुश , बहुत अधिक शामिल है, लेकिन आप वहाँ हैं। भले ही, इस पागल गतिशील दुनिया में, JSON के साथ ऑब्जेक्ट्स को प्रारंभ करने का तरीका जानना आपके पीछे की जेब में खराब कौशल नहीं है।

+0

आपके सुझावों के लिए धन्यवाद # 1 एक सभ्य कामकाज की तरह लगता है। # 2 कुछ परिदृश्यों के लिए एक अच्छा समाधान है, लेकिन सभी परिदृश्यों के लिए काम नहीं करता है। और # 3 ... ओवरकिल के बारे में बात करें, लेकिन बॉक्स के बाहर सोचने के लिए धन्यवाद! –

+0

दिलचस्प है, समाधान # 3 समय की परीक्षा में खड़े होने की संभावना है, क्योंकि इस तकनीक का उपयोग करने के लिए आप जिस अतिरिक्त विशेषताओं को उपयोग करना चाहते हैं, सीधे जेसनएट्रिब्यूट से प्राप्त किया जा सकता है। लेकिन यदि एक गैर-संकलन समाधान वह है जो आप बाद में हैं, तो मैं हूं अन्य उत्तरों में से कुछ आपके पसंद के लिए अधिक होंगे .-) –

+0

यह सच है, आपके समाधान केवल संकलित हैं :) –

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

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