2009-12-13 44 views
12

मैं सी # में प्रतिबिंब के बारे में पढ़ रहा हूं और सीख रहा हूं। यह जानना अच्छा होगा कि यह मेरे दैनिक काम में मेरी मदद कैसे कर सकता है, इसलिए मैं चाहता हूं कि मेरे से अधिक अनुभव वाले लोग मुझे नमूने या विचार बताएं कि हम इसका उपयोग किस प्रकार की चीजें प्राप्त कर सकते हैं, या हम कोड की मात्रा को कैसे कम कर सकते हैं हम लिखते हैं।प्रतिबिंब। हम इसका उपयोग करके क्या हासिल कर सकते हैं?

धन्यवाद।

+1

संबंधित प्रश्न: http://stackoverflow.com/questions/1859902/in-3-minutes-what-is-reflection –

+1

संबंधित हां, लेकिन मुझे व्यक्तिगत रूप से लगता है कि प्रश्न बल्कि अनुपयोगी है। एकीकरण रिवर्स व्युत्पन्न कैलकुस है, लेकिन मैं आपको बता रहा हूं कि आपको कुछ भी नहीं सिखाया गया है, भले ही आपको पता चले कि व्युत्पन्न क्या है। : डी –

उत्तर

10

मैं हाल ही में यह रिवाज मेरी enum में खेतों विशेषताएं जोड़ने के लिए इस्तेमाल किया:

public enum ShapeName 
{ 
    // Lines 
    [ShapeDescription(ShapeType.Line, "Horizontal Scroll Distance", "The horizontal distance to scroll the browser in order to center the game.")] 
    HorizontalScrollBar, 
    [ShapeDescription(ShapeType.Line, "Vertical Scroll Distance", "The vertical distance to scroll the browser in order to center the game.")] 
    VerticalScrollBar, 
} 

प्रतिबिंब का उपयोग क्षेत्र पाने के लिए:

public static ShapeDescriptionAttribute GetShapeDescription(this ShapeName shapeName) 
    { 
     Type type = shapeName.GetType(); 
     FieldInfo fieldInfo = type.GetField(shapeName.ToString()); 
     ShapeDescriptionAttribute[] attribs = fieldInfo.GetCustomAttributes(typeof(ShapeDescriptionAttribute), false) as ShapeDescriptionAttribute[]; 

     return (attribs != null && attribs.Length > 0) ? attribs[0] : new ShapeDescriptionAttribute(ShapeType.NotSet, shapeName.ToString()); 
    } 

विशेषता वर्ग:

[AttributeUsage(AttributeTargets.Field)] 
public class ShapeDescriptionAttribute: Attribute 
{ 
    #region Constructor 
    public ShapeDescriptionAttribute(ShapeType shapeType, string name) : this(shapeType, name, name) { } 

    public ShapeDescriptionAttribute(ShapeType shapeType, string name, string description) 
    { 
     Description = description; 
     Name = name; 
     Type = shapeType; 
    } 
    #endregion 

    #region Public Properties 
    public string Description { get; protected set; } 

    public string Name { get; protected set; } 

    public ShapeType Type { get; protected set; } 
    #endregion 
} 
9

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

दृश्य स्टूडियो में Intellisense आप वस्तुओं का प्रयोग कर रहे के बारे में जानकारी देने के लिए प्रतिबिंब का उपयोग करता है।

ध्यान दें कि प्रतिबिंब का उपयोग लागत पर आता है। किसी ऑब्जेक्ट को प्रतिबिंबित करना धीमा हो सकता है। लेकिन अगर आपको इसकी ज़रूरत है तो प्रतिबिंब एक बहुत ही उपयोगी टूल है।

+1

आप उन लागतों को विभिन्न तरीकों से कम कर सकते हैं; प्रतिबिंब-आधारित कोड नियमित कोड के रूप में तेज़ हो सकता है। –

0

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

0

यहाँ यह बिना कुछ बातें मुझे लगता है कि के लिए प्रतिबिंब का उपयोग किया है बेहद मुश्किल या असंभव हो जाएगा रहे हैं:

  • StringTemplate templating इंजन का मेरा सी # बंदरगाह। प्रतिबिंब का उपयोग गतिशील वस्तुओं के गुणों को पुनः प्राप्त करने के लिए किया जाता है।
  • प्रबंधित कोड में लिखित एक सीएलआई जेआईटी कंपाइलर।

Managed Extensibility Framework (एक नई नेट पुस्तकालय) के लिए प्रतिबिंब का उपयोग करता है:

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

कई लोगों के बीच एक उपयोग: आप एक प्लग-इन आर्किटेक्चर बना सकते हैं जहां आप कॉन्फ़िगरेशन फ़ाइल में क्लास-टू-यूज का नाम निर्दिष्ट करते हैं। प्रतिबिंब का उपयोग करके आप इस स्ट्रिंग को ले सकते हैं और अनुरोध किए गए ऑब्जेक्ट का एक उदाहरण बना सकते हैं। यदि वह ऑब्जेक्ट ज्ञात इंटरफ़ेस लागू करता है, तो आप इसे सामान्य (गैर प्रतिबिंब) कोड के माध्यम से उपयोग कर सकते हैं।

1

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

यह अंतिम उत्पादन में नहीं आया, आपको दिमाग में, लेकिन पुनरावृत्त चरण के दौरान कुछ बॉयलरप्लेट को हटा दिया जाना चाहिए, मुझे बदलने की आवश्यकता होगी।

1

मैंने अपने रूपों पर लेबल और बटन जैसे नियंत्रणों के अनुवाद की सुविधा के लिए प्रतिबिंब का उपयोग किया। प्रतिबिंब का उपयोग करके मैं अपने फॉर्म पर सभी नियंत्रणों के माध्यम से जाऊंगा और एक XML फ़ाइल में नियंत्रण नाम, टेक्स्ट और शीर्षक लिखूंगा। एक्सएमएल में नियंत्रण शीर्षक और पाठ का अनुवाद करने के बाद, फाइल को प्रत्येक नियंत्रण के शीर्षक और XML में पाए गए पाठ को इसके अनुवादित मानों में सेट करने के लिए वापस पढ़ा जाता है।
हमारे रूपों को कई अलग-अलग भाषाओं में अनुवादित करने की आवश्यकता है और प्रतिबिंब का उपयोग करने से हमें बहुत समय बचाया जा सकता है।

-1

नेट फ्रेमवर्क के मैकेनिक्स को बेहतर ढंग से समझने के लिए Red Gate .Net Reflector का उपयोग करने के लिए मेरे पास क्लासिक उपयोग है। कभी सोचा कि कैसे या क्यों एक विशेष रूप से ढांचा ऑब्जेक्ट जिस तरह से काम करता है या आप कभी भी थोड़ी देर तक फंस गए हैं, क्यों कुछ ऐसा नहीं करता है जैसा आपने सोचा था कि ऐसा नहीं होगा?

कभी-कभी दस्तावेज कम से कम कहने के लिए थोड़ा सा शर्मीला हो सकता है लेकिन रेडगेट द्वारा प्रतिबिंब और टूल का उपयोग करके आप फ्रेमवर्क कोड में घूम सकते हैं ताकि यह समझ सके कि यह कैसे/क्यों/सब कुछ है।

प्रतिबिंब का उपयोग करके "एमएस बाहरी" के माध्यम से सीएलआर कोड में कुछ से अधिक बग पाए गए हैं।

+1

मुझे जांचना होगा, लेकिन मुझे यकीन नहीं है कि परावर्तक प्रतिबिंब का उपयोग करता है; मैं प्रतिबिंब एपीआई का उपयोग करने के बजाय आईएल को सीधे पढ़ा और पार्स किया था। –

3

लाइब्रेरी कोड के लिए यह अमूल्य है जिसे कॉलर के बारे में जानने की आवश्यकता नहीं है - जेनेरिक के साथ, लेकिन डेटा तक अमीर पहुंच। उदाहरण:

  • ORMs (भौतिकीकरण आदि)
  • क्रमबद्धता/अक्रमांकन
  • वस्तु क्लोनिंग/गहरी प्रतिलिपि
  • यूआई/बाध्यकारी कोड (सख्ती से इस ComponentModel है, लेकिन आप दो मिश्रण कर सकते हैं - के लिए उदाहरण, हाइपरडिस्क्रिप्टर)

आपको निश्चित रूप से प्रतिबिंब की मात्रा को कम करने की कोशिश करनी चाहिए, लेकिन आप प्रतिनिधियों को कैश करके लागत को कम कर सकते हैं ओम Delegate.CreateDelegate/Expression/DynamicMethod

1

प्रतिबिंब वी.एस. में गुण विंडो है आधारित - यदि आप एक उपयोगकर्ता नियंत्रण आप PropertyGrid (अपनी भी एक नियंत्रण अगर आप चाहते हैं कि आप उपयोग कर सकते हैं) तुरन्त से इस पर कोई गुण संशोधित कर सकते हैं। बेशक आप इसे प्रदर्शित करने के लिए विशेषताओं को जोड़ सकते हैं (जिसे प्रतिबिंब के माध्यम से उपयोग किया जाता है)।

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

यहां मेरे पास एक कक्षा है जहां मैं इसे क्रमबद्ध करने/डी-क्रमबद्ध करने के प्रतिबिंब का उपयोग करता हूं - और अतिरिक्त यूआई जानकारी के लिए विशेषताओं को प्रदान करता हूं।

[TypeConverter(typeof(IndexedExpandableObjectConverter))] 
[BinarySerializeable] 
public sealed class Socket 
{ 
    #region Fields (7)  

    [SerializedPosition(0)] 
    Byte _mode = 1; 

    ... 

    [SerializedPositionAttribute(4)] 
    UInt16 _localPort; 

    ... 

#region गुण (5)

[DisplayName("Listning Port")] 
    [Description("The port which the socket will listen for connections on")] 
    [DisplayIndex (0)] 
    public UInt16 LocalPort 
    { 
     get { return _localPort; } 
     set { _localPort = value; } 
    } 

    ... 

और क्रमबद्धता समारोह - के रूप में आप देख सकते हैं, यह सिर्फ एक वस्तु और बाइट क्रम (endianness) आप चाहते हैं लेता है। बाकी सब कुछ प्रतिबिंब द्वारा निर्धारित किया जाता है। डिफ़ॉल्ट SerializationProvider ऑब्जेक्ट (निजी या नहीं) के भीतर फ़ील्ड पर SerializedPosition विशेषताओं का उपयोग करके काम करता है।

public static Byte[] Serialize(Object obj, ByteOrder streamOrder) 
{ 

    var provider = GetProvider(obj); 

    if (provider.CanSerialize(obj.GetType())) 
     return provider.Serialize(obj, streamOrder); 

    throw new ArgumentException(obj.GetType() + " is non-serialisable by the specified provider '" + provider.GetType().FullName + "'."); 
} 


private static IBinarySerializatoinProvider GetProvider(Object obj) 
{ 

    var providerAttrib = Reflector.GetAttribute<BinarySerializationProviderAttribute>(obj); 

    if (providerAttrib != null) 
     return CreateProvider(providerAttrib.ProviderType); 

    return CreateProvider(typeof(SerializationProvider)); 
} 
0

मुझे लगता है कि एक "स्वतंत्र" आवेदन, हर जगह ऑब्जेक्ट का उपयोग संकलन समय पर में जाना जाता है, तो आप प्रतिबिंब ज्यादा प्रयोग नहीं करते।

लेकिन जब आप लाइब्रेरी या फ्रेमवर्क कोड लिखते हैं जो उन वस्तुओं का उपयोग करना चाहिए जो संकलित समय पर पूरी तरह से ज्ञात नहीं हैं (पूरी तरह से - आप इंटरफेस या बेसक्लास के बारे में जानते हैं), प्रतिबिंब उन वस्तुओं के साथ काम करने के लिए अमूल्य हो सकता है।

1

यह एक enum या एक जादू स्ट्रिंग पर आधारित विधियों पर अमल करने तरीका है ...


    public enum ReflectionTestMethods 
    { 
     MethodA, 
     MethodB, 
     MethodC 
    } 
    public class ReflectionTest 
    { 

     public void Execute(ReflectionTestMethods method) 
     { 
      MethodInfo methodInfo = GetType().GetMethod(method.ToString() 
       , BindingFlags.Instance | BindingFlags.NonPublic); 
      if (methodInfo == null) throw new NotImplementedException(method.ToString()); 
      methodInfo.Invoke(this, null); 
     } 

     private void MethodA() 
     { 
      Debug.Print("MethodA"); 
     } 

     private void MethodB() 
     { 
      Debug.Print("MethodB"); 
     } 

     private void MethodC() 
     { 
      Debug.Print("MethodC"); 
     } 
    } 

लेकिन यह शायद एक बेहतर समाधान है ...


    public class ActionTest 
    { 
     private readonly Dictionary _actions = new Dictionary(); 

     public ActionTest() 
     { 
      _actions.Add(ReflectionTestMethods.MethodA.ToString(), new Action(MethodA)); 
      _actions.Add(ReflectionTestMethods.MethodB.ToString(), new Action(MethodB)); 
      _actions.Add(ReflectionTestMethods.MethodC.ToString(), new Action(MethodC)); 
     } 

     public void Execute(ReflectionTestMethods method) 
     { 
      if (!_actions.ContainsKey(method.ToString())) 
       throw new NotImplementedException(method.ToString()); 
      _actions[method.ToString()](); 
     } 

     private void MethodA() 
     { 
      Debug.Print("MethodA"); 
     } 

     private void MethodB() 
     { 
      Debug.Print("MethodB"); 
     } 
     private void MethodC() 
     { 
      Debug.Print("MethodC"); 
     } 
    } 
0

मैं के लिए इसका इस्तेमाल करते हैं:

  • निर्भरता इंजेक्शन
  • की माइक्रोसॉफ्ट कमी के लिए
  • समाधान प्रेरणा तरह बातें जोड़ने के लिए "covariant/contravariant सामान्य" और "नई() पैरामीटर के साथ की कमी"
  • पहलू उन्मुख प्रोग्रामिंग (कुछ हद तक, ज्यादातर मैं PostSharp का उपयोग)
0

कुछ विचार "लेट बाइंडिंग के लिए" अच्छे हैं समाधान जहां आप अपने प्रोजेक्ट से जुड़े भौतिक संदर्भ नहीं चाहते हैं बल्कि बाद में इसे "कनेक्ट" करें। इस तरह यदि संदर्भ वहां नहीं है और यह महत्वपूर्ण नहीं है, तो आपको अनुपलब्ध संदर्भों की कोई अनचाहे त्रुटियां नहीं मिलती हैं। आपको एक नियंत्रित त्रुटि मिलती है जिसे आप संभाल सकते हैं।

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