2008-08-21 13 views

उत्तर

140

मेटाडाटा पर एक ट्यूटोरियल है। आपकी वस्तुओं/विधियों/गुणों के बारे में डेटा।

उदाहरण के लिए मैं एक विशेषता घोषित कर सकता हूं: DisplayOrder ताकि मैं यूआई में ऑर्डर गुणों को आसानी से नियंत्रित कर सकूं। मैं इसे कक्षा में जोड़ सकता हूं और कुछ जीयूआई घटकों को लिख सकता हूं जो गुणों को निकालें और यूआई तत्वों को उचित तरीके से ऑर्डर करें।

public class DisplayWrapper 
{ 
    private UnderlyingClass underlyingObject; 

    public DisplayWrapper(UnderlyingClass u) 
    { 
     underlyingObject = u; 
    } 

    [DisplayOrder(1)] 
    public int SomeInt 
    { 
     get 
     { 
      return underlyingObject .SomeInt; 
     } 
    } 

    [DisplayOrder(2)] 
    public DateTime SomeDate 
    { 
     get 
     { 
      return underlyingObject .SomeDate; 
     } 
    } 
} 

इस प्रकार यह सुनिश्चित करना कि मेरे कस्टम जीयूआई घटकों के साथ काम करते समय कुछ आईडी हमेशा से पहले प्रदर्शित होता है।

हालांकि, आप उन्हें सीधे कोडिंग वातावरण के बाहर उपयोग किए जाने वाले सबसे अधिक उपयोग करेंगे। उदाहरण के लिए, विंडोज डिज़ाइनर उन्हें बड़े पैमाने पर उपयोग करता है, इसलिए यह जानता है कि कस्टम बनाई गई वस्तुओं से कैसे निपटें। इसलिए जैसे BrowsableAttribute का उपयोग करना:

[Browsable(false)] 
public SomeCustomType DontShowThisInTheDesigner 
{ 
    get{/*do something*/} 
} 

डिजाइनर बताता है उदाहरण के लिए डिजाइन समय में गुण विंडो में उपलब्ध संपत्तियों में इस सूची नहीं।

आप कोड कोडिंग, प्री-कंपाइल ऑपरेशंस (जैसे पोस्ट-शार्प) या रन-टाइम ऑपरेशंस जैसे रिफ्लेक्शन.इमिट के लिए भी उनका उपयोग कर सकते हैं। उदाहरण के लिए, आप प्रोफाइलिंग के लिए थोड़ा सा कोड लिख सकते हैं जो पारदर्शी रूप से लिपटे प्रत्येक कोड को आपके कोड बनाता है और इसे बार-बार दबाता है। आप विशेष तरीकों पर रखे गए एक विशेषता के माध्यम से समय का "ऑप्ट-आउट" कर सकते हैं।

public void SomeProfilingMethod(MethodInfo targetMethod, object target, params object[] args) 
{ 
    bool time = true; 
    foreach (Attribute a in target.GetCustomAttributes()) 
    { 
     if (a.GetType() is NoTimingAttribute) 
     { 
      time = false; 
      break; 
     } 
    } 
    if (time) 
    { 
     StopWatch stopWatch = new StopWatch(); 
     stopWatch.Start(); 
     targetMethod.Invoke(target, args); 
     stopWatch.Stop(); 
     HandleTimingOutput(targetMethod, stopWatch.Duration); 
    } 
    else 
    { 
     targetMethod.Invoke(target, args); 
    } 
} 

उन्हें घोषित करना आसान है, केवल एक वर्ग जो विशेषता से विरासत में मिलता है।

public class DisplayOrderAttribute : Attribute 
{ 
    private int order; 

    public DisplayOrderAttribute(int order) 
    { 
     this.order = order; 
    } 

    public int Order 
    { 
     get { return order; } 
    } 
} 

और याद रखें कि जब आप विशेषता का उपयोग आप प्रत्यय "विशेषता" संकलक आप के लिए है कि जोड़ना होगा छोड़ सकते हैं।

+30

इसके लायक होने के लिए, यह सभी की एक सूची है (निर्मित) .NET विशेषताएं: http://msdn.microsoft.com/en-us/library/aa311259(VS.71).aspx – wprl

+1

आप अपनी "SomeProfilingMethod" को एक विशेषता के रूप में कैसे उपयोग करेंगे? – RayLoveless

+0

@RayLoveless यह एक विशेषता नहीं है, SomeProfilingMethod एक उपकरण कोड है जो प्रोफाइलिंग गुणों की तलाश में है। विशेष रूप से उदाहरण में मैंने इसे "ऑप्ट-इन" एक के विपरीत "ऑप्ट-आउट" विशेषता (NoTimingAttribute) की तलाश की। विचार यह है कि यह सब कुछ समय। – Quibblesome

4

एक विशेषता एक कक्षा है जिसमें कुछ कार्यक्षमता शामिल है जिसे आप अपने कोड में ऑब्जेक्ट्स पर लागू कर सकते हैं। एक बनाने के लिए, System.Attribute से विरासत प्राप्त करने वाली कक्षा बनाएं।

उनके लिए क्या अच्छा है ... उनके लिए लगभग असीमित उपयोग हैं।

http://www.codeproject.com/KB/cs/dotnetattributes.aspx

+1

"कार्यक्षमता" यहां गलत शब्द है; वे metadata हैं, कार्यक्षमता नहीं –

4

गुण कक्षाएं, तरीकों या विधानसभाओं के लिए आवेदन किया मेटाडाटा की तरह हैं।

वे किसी भी चीज के लिए अच्छे हैं (डीबगर विज़ुअलाइज़ेशन, चीजों को अप्रचलित के रूप में चिह्नित करना, चीजों को क्रमबद्ध करने के रूप में चिह्नित करना, सूची अंतहीन है)।

अपने स्वयं के कस्टम वाले बनाना पाई के रूप में आसान है। यहां से शुरू करें:

http://msdn.microsoft.com/en-us/library/sw480ze8(VS.71).aspx

2

आप कस्टम प्रत्येक उपवर्ग के लिए फिर से पर एक ही कोड लिखने के बिना उप वर्गों में टैग मान निर्धारित करने के लिए एक सरल तरीके के रूप में विशेषताओं का उपयोग कर सकते हैं। मैं अपने कोड में कस्टम विशेषताओं को परिभाषित करने और उपयोग करने के तरीके के बारे में एक अच्छी concise example by John Waters पर आया था।

http://msdn.microsoft.com/en-us/library/aa288454(VS.71).aspx

12

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

एक विशेषता बनाने के द्वारा प्रारंभ:

[AttributeUsage(AttributeTargets.Class, AllowMultiple=false, Inherited=true)] 
public class SortOrderAttribute : Attribute 
{ 
    public int SortOrder { get; set; } 

    public SortOrderAttribute(int sortOrder) 
    { 
     this.SortOrder = sortOrder; 
    } 
} 

सभी विशेषता वर्गों प्रत्यय "गुण" मान्य होने के लिए होना आवश्यक है।
ऐसा करने के बाद, विशेषता का उपयोग करने वाली कक्षा बनाएं।

[SortOrder(23)] 
public class MyClass 
{ 
    public MyClass() 
    { 
    } 
} 

अब आप ऐसा करके एक विशिष्ट वर्ग 'SortOrderAttribute जांच कर सकते हैं (अगर यह एक है) के बाद:

public class MyInvestigatorClass 
{ 
    public void InvestigateTheAttribute() 
    { 
     // Get the type object for the class that is using 
     // the attribute. 
     Type type = typeof(MyClass); 

     // Get all custom attributes for the type. 
     object[] attributes = type.GetCustomAttributes(
      typeof(SortOrderAttribute), true); 

     // Now let's make sure that we got at least one attribute. 
     if (attributes != null && attributes.Length > 0) 
     { 
      // Get the first attribute in the list of custom attributes 
      // that is of the type "SortOrderAttribute". This should only 
      // be one since we said "AllowMultiple=false". 
      SortOrderAttribute attribute = 
       attributes[0] as SortOrderAttribute; 

      // Now we can get the sort order for the class "MyClass". 
      int sortOrder = attribute.SortOrder; 
     } 
    } 
} 

आप इस बारे में और अधिक पढ़ने के लिए चाहते हैं, तो आप हमेशा बाहर MSDN जांच कर सकते हैं जो है एक बहुत अच्छा विवरण।
मुझे उम्मीद है कि इससे आपकी मदद की जाएगी!

3

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

गुणों का उपयोग करना और उनके उपयोग के लिए उपयुक्त परिदृश्यों को जानना काम का बड़ा हिस्सा है।

4

प्रोजेक्ट में मैं वर्तमान में काम कर रहा हूं, विभिन्न स्वादों की यूआई ऑब्जेक्ट्स का एक सेट है और मुख्य ऑब्जेक्ट में उपयोग के लिए पेज बनाने के लिए इन ऑब्जेक्ट्स को असेंबली करने के लिए एक संपादक है, जो डेवस्टूडियो में फॉर्म डिज़ाइनर जैसा है। ये वस्तुएं अपनी स्वयं की असेंबली में मौजूद हैं और प्रत्येक वस्तु UserControl से ली गई कक्षा है और इसमें एक कस्टम विशेषता है। यह विशेषता इस तरह परिभाषित किया गया है:

[AttributeUsage (AttributeTargets::Class)] 
public ref class ControlDescriptionAttribute : Attribute 
{ 
public: 
    ControlDescriptionAttribute (String ^name, String ^description) : 
    _name (name), 
    _description (description) 
    { 
    } 

    property String ^Name 
    { 
    String ^get() { return _name; } 
    } 

    property String ^Description 
    { 
    String ^get() { return _description; } 
    } 

private: 
    String 
    ^_name, 
    ^_description; 
}; 

और मैं इस तरह एक वर्ग में इसे लागू:

[ControlDescription ("Pie Chart", "Displays a pie chart")] 
public ref class PieControl sealed : UserControl 
{ 
    // stuff 
}; 

है जो पिछले पोस्टर कहा है।

विशेषता का उपयोग करने के लिए, संपादक के पास Generic::List <Type> नियंत्रण प्रकार होता है। एक सूची बॉक्स है जो उपयोगकर्ता नियंत्रण के उदाहरण बनाने के लिए पृष्ठ से खींच और ड्रॉप कर सकता है। सूची बॉक्स पॉप्युलेट करने के लिए, मैं नियंत्रण के लिए ControlDescriptionAttribute हो और सूची में एक प्रविष्टि को भरें:

// done for each control type 
array <Object ^> 
    // get all the custom attributes 
    ^attributes = controltype->GetCustomAttributes (true); 

Type 
    // this is the one we're interested in 
    ^attributetype = ECMMainPageDisplay::ControlDescriptionAttribute::typeid; 

// iterate over the custom attributes 
for each (Object ^attribute in attributes) 
{ 
    if (attributetype->IsInstanceOfType (attribute)) 
    { 
    ECMMainPageDisplay::ControlDescriptionAttribute 
     ^description = safe_cast <ECMMainPageDisplay::ControlDescriptionAttribute ^> (attribute); 

    // get the name and description and create an entry in the list 
    ListViewItem 
     ^item = gcnew ListViewItem (description->Name); 

    item->Tag = controltype->Name; 
    item->SubItems->Add (description->Description); 

    mcontrols->Items->Add (item); 
    break; 
    } 
} 

ध्यान दें: ऊपर है C++/CLI लेकिन यह सी # कन्वर्ट करने के लिए मुश्किल नहीं है (हाँ, मैं पता है, सी ++/सीएलआई एक घृणित है लेकिन मुझे इसके साथ काम करना है :-()

आप ज्यादातर चीजों पर विशेषताओं को डाल सकते हैं और पूर्वनिर्धारित विशेषताओं की पूरी श्रृंखला हैं। ऊपर वर्णित संपादक भी कस्टम विशेषताओं को देखता है गुण जो संपत्ति का वर्णन करते हैं और इसे कैसे संपादित करें।

एक बार जब आप पूरा विचार प्राप्त कर लेंगे, यो आप सोचेंगे कि आप उनके बिना कभी कैसे रहते थे।

3

गुण हैं, अनिवार्य रूप से, डेटा के टुकड़े आप अपने प्रकार के लिए संलग्न करने के लिए (कक्षाएं, तरीकों, घटनाओं, enums, आदि)

विचार है चाहता हूँ कि रन टाइम पर कुछ अन्य प्रकार/रूपरेखा/उपकरण पर क्वेरी करेगा विशेषता में जानकारी के लिए टाइप करें और उस पर कार्य करें।

तो, उदाहरण के लिए, विजुअल स्टूडियो एक तीसरे पक्ष के नियंत्रण पर विशेषताओं से पूछताछ कर सकता है कि यह पता लगाने के लिए कि कौन से गुण डिज़ाइन समय पर गुण फलक में दिखने चाहिए।

एस्पेक्ट्स ओरिएंट ओरिएंटेड प्रोग्रामिंग में विशेषताओं का उपयोग उन वस्तुओं पर आधारित वस्तुओं को इंजेक्ट/हेरफेर करने के लिए भी किया जा सकता है जो उन्हें सजाने वाले गुणों के आधार पर ऑब्जेक्ट को इंजेक्ट/हेरफेर करते हैं और ऑब्जेक्ट के व्यावसायिक तर्क को प्रभावित किए बिना ऑब्जेक्ट्स में सत्यापन, लॉगिंग इत्यादि जोड़ते हैं।

2

एक विशेषता बनाने शुरू करने के लिए, एक सी # स्रोत फ़ाइल खोलें, attribute टाइप करें और [TAB] दबाएं। यह एक नई विशेषता के लिए एक टेम्पलेट में विस्तार होगा।

+5

यह प्रश्न का उत्तर कैसे देता है? यह एक टिप्पणी होनी चाहिए, जवाब नहीं। – gdoron

35

बहुत से लोग जवाब दे दिया है, लेकिन कोई भी इस अब तक ...

गुण प्रतिबिंब के साथ भारी उपयोग किया जाता है का उल्लेख किया गया है। प्रतिबिंब पहले से ही धीमा है।

यह बहुत सार्थक आपके कस्टम गुणों को sealed कक्षाओं के रूप में चिह्नित करने के लिए अपने रनटाइम प्रदर्शन को बेहतर बनाने के लिए चिह्नित करता है।

यह भी विचार करना एक अच्छा विचार है कि इस तरह की विशेषता का उपयोग करने के लिए उचित होगा, और AttributeUsage के माध्यम से इसे इंगित करने के लिए अपनी विशेषता (!) को विशेषता दें। उपलब्ध विशेषता उपयोगों की सूची आपको आश्चर्य हो सकता है:

  • विधानसभा
  • मॉड्यूल
  • कक्षा
  • Struct
  • Enum
  • निर्माता
  • विधि
  • संपत्ति
  • फील्ड
  • घटना
  • इंटरफ़ेस
  • पैरामीटर
  • प्रतिनिधि
  • ReturnValue
  • GenericParameter
  • सभी

यह भी शांत है कि AttributeUsage विशेषता AttributeUsage विशेषता के हस्ताक्षर का हिस्सा है। परिपत्र निर्भरताओं के लिए वाह!

[AttributeUsageAttribute(AttributeTargets.Class, Inherited = true)] 
public sealed class AttributeUsageAttribute : Attribute 
1

विशेषताएं आमतौर पर पहलू ओरिएंटेड प्रोग्रामिंग के लिए भी उपयोग की जाती हैं। इस उदाहरण के लिए PostSharp प्रोजेक्ट देखें।

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