2009-12-17 10 views
16

मैं कुछ वर्गों कि एक निश्चित इंटरफ़ेस को लागू नहीं लेकिन संरचना की दृष्टि से है कि इंटरफ़ेस का पालन करना है लागू करने के लिए एक आवरण बनाने।स्वचालित रूप से एक अंतरफलक

interface IFoo { 
    void method(); 
} 

class Bar { // does not implement IFoo 
    public void method() {...} 
} 

अब, मैं उन कक्षाओं कि बस लिपटे वर्ग

class BarWrapper : IFoo { 
    Bar bar = new Bar(); 
    public void method() 
    { 
     bar.method(); 
    } 
} 

प्रतिनिधि के चारों ओर एक आवरण लिख सकता है लेकिन यह कठिन काम के बहुत सारे है। क्या वे रैपर वर्ग किसी भी तरह से स्वचालित रूप से उत्पन्न हो सकते हैं? कुछ की तरह:

IFoo foo = CreateWrapper<IFoo>(new Bar());

मैं तुम्हें Reflection.Emit साथ ऐसा कर सकता है यकीन है, लेकिन मुझे लगता है कि उपयोग नहीं किया है और यह पहली नज़र में बहुत आसान नहीं लगती है।

वहाँ एक आसान तरीका है या शायद एक पुस्तकालय है कि पहले से ही इस लागू करता है?

+0

आप लिखने के लिए होने अंत तो यह स्वयं, यह एक संबंधित उदाहरण के रूप में मदद कर सकता है: http://stackoverflow.com/questions/847809/how-can-i-write-a-generic-container-class-that-implements-a-given-interface-in -सी/847975 # 847975 –

उत्तर

2

आप कैसल परियोजना की DynamicProxy को देखने के लिए चाहते हो सकता है। Rhino.Mocks इसके प्रकार के प्रॉक्सिंग के लिए उपयोग करता है।

मैं इसे अपने आप का इस्तेमाल किया है नहीं है, इसलिए मैं नहीं जानता कि कितना प्रयास यह अपनी ओर से की आवश्यकता होगी, लेकिन मुझे लगता है कि यह एक अच्छी शुरुआत है।

+0

AFAIK, गतिशील प्रॉक्सी का वर्तमान संस्करण केवल काम करता है इंटरफेस और कंक्रीट प्रकार, और केवल आभासी तरीकों को रोक सकते हैं। यह मैपिंग नहीं करता है। हालांकि, यह भविष्य में इसे संबोधित कर सकता है: http://using.castleproject.org/display/CASTLE/Dynamic+Proxy+3+design+meeting ("टाइप रैपिंग" तक नीचे स्क्रॉल करें) –

+0

@ मार्क: प्रश्न केवल उल्लेख इंटरफेस के साथ काम करना, ताकि यह मेरे लिए प्रासंगिक महत्वपूर्ण प्रतिबंध की तरह न लगे। –

+0

@ जोन स्कीट: हाँ, लेकिन वह एक ठोस वर्ग को लपेटना/प्रॉक्सी करना चाहता है जो न तो इंटरफ़ेस लागू करता है और न ही वर्चुअल विधियां है, इसलिए मुझे लगता है कि यह बहुत प्रासंगिक है। –

0

आप .NET 4 उपयोग करने के लिए तैयार हैं, तो एक समाधान एक DynamicObject के रूप में आवरण वर्ग को परिभाषित, और प्रतिबिंब का उपयोग करके लपेटा वर्ग के लिए कॉल करने के लिए गतिशील तरीकों के लिए कॉल कन्वर्ट करने के लिए हो सकता है (मुझे यकीन है कि नहीं कर रहा हूँ अगर वह वास्तव में कम काम करेगा, वैसे भी, प्रतिबिंब के उपयोग से जुड़े संभावित प्रदर्शन चिंताओं को भी ध्यान में रखें)।

0

हालांकि मैंने उन्हें स्वयं नहीं उपयोग किया है, मुझे लगता है कि विजुअल स्टूडियो में टी 4 टेम्पलेट्स का उपयोग गतिशील प्रकार link text की कोड जनरेशन के लिए किया जा सकता है।

0

यहाँ एक अलग जेनरिक का उपयोग कर तरीका है। इसके लिए थोड़ा और काम विचार की आवश्यकता होगी। आपको प्रत्येक इंटरफ़ेस के लिए एक रैपर लागू करने और प्रतिबिंब के साथ सभी विधियों को कॉल करने की आवश्यकता है।

class FooWrapper<T> : IFoo 
{ 
    private T obj; 

    public FooWrapper(T obj) 
    { 
     this.obj = obj; 
    } 

    public void method() 
    { 
     // call method with reflection 
     // obj.method(); 
    } 
} 

IFoo foo = new FooWrapper(new Bar()); 
+0

+1: वही करेगा। इसके अलावा प्रतिबिंब –

+1

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

8

जो आप पूरा करने की कोशिश कर रहे हैं, उसे बतख टाइपिंग के नाम से जाना जाता है। कुछ समर्पित पुस्तकालय हैं जो आपको ऐसा करने देंगे, हालांकि मैंने उनमें से किसी का भी उपयोग नहीं किया है।

थोड़ा प्रयास (और कुछ प्रतिबिंब) के साथ आप कैसल डायनैमिक प्रॉक्सी का उपयोग कर सकते हैं, here रूपरेखा के दृष्टिकोण का उपयोग करके।

अगर किसी कारण से इंटरसेप्टर आधारित दृष्टिकोण आपके लिए स्वीकार्य नहीं होगा, तो डायनामिक प्रॉक्सी बॉक्स (अभी तक) से इसका समर्थन नहीं करता है, लेकिन यदि आप संस्करण 2.2 बीटा का उपयोग करते हैं, तो यह प्रदान करना काफी आसान होगा कि दृढ़ता से टाइप किया गया तरीका (इंटरसेप्टर्स का उपयोग किए बिना), अपना प्रॉक्सी प्रकार बिल्डर प्रदान करके (देखें कि मिश्रित कैसे कार्यान्वित किए जाते हैं)।

+1

+1 शामिल होने के लिए धन्यवाद :) –

3

आप एक नया वर्ग

class SubBar : IFoo, Bar { 
} 

बना सकते हैं और दृष्टांत है कि हो सकता है (यह मानते हुए बार सही मायने में ducktype है, अर्थात, सटीक IFoo विधियां)।

5

यदि आप हल्के और सरल डक टाइपिंग समर्थन चाहते हैं, तो आप यह भी देख सकते हैं: Duck Typing project। यह .NET 2.0 और नए के साथ काम करता है।

प्रयोग उदाहरण (David Meyer's site से लिया गया):

public interface ICanAdd 
{ 
    int Add(int x, int y); 
} 

// Note that MyAdder does NOT implement ICanAdd, 
// but it does define an Add method like the one in ICanAdd: 
public class MyAdder 
{ 
    public int Add(int x, int y) 
    { 
     return x + y; 
    } 
} 

public class Program 
{ 
    void Main() 
    { 
     MyAdder myAdder = new MyAdder(); 

     // Even though ICanAdd is not implemented by MyAdder, 
     // we can duck cast it because it implements all the members: 
     ICanAdd adder = DuckTyping.Cast<ICanAdd>(myAdder); 

     // Now we can call adder as you would any ICanAdd object. 
     // Transparently, this call is being forwarded to myAdder. 
     int sum = adder.Add(2, 2); 
    } 
} 

विस्तार तरीकों का उपयोग करना, आप इसे कुछ इस तरह में आसान बनाने में कर सकता है (simlar Bart De Smet's वाक्य रचना के लिए)

MyAdder myAdder = new MyAdder(); // this doesn't implement the interface 
ICanAdd adder = myAdder.AsIf<ICanAdd>(); // but it quacks like a duck 
int sum = adder.Add(2, 2);