2012-09-17 20 views
10

कुछ वर्ग विधि में, ए, मुझे लाइब्रेरी विधि बी को कॉल करने की आवश्यकता है, जो पैरामीटर के रूप में IProgress<Object> के रूप में लेता है।सी # क्या इंटरफ़ेस की आवश्यकता होने पर लैम्बडा की आपूर्ति करना संभव है?

आम तौर पर, मैं या तो कक्षा के हिस्से के रूप में IProgress<Object> लागू कर सकता हूं जहां ए रहता है, और उसके बाद "यह" विधि बी को पास कर सकता है या शायद मैं एक नई कक्षा बना सकता हूं जिसका एकमात्र उद्देश्य IProgress<Object> को लागू करना है और इसे सही तरीके से संभालना है-- फिर इस मामले में मैं उस वर्ग का एक उदाहरण बनाउंगा और बी

परन्तु जो मैं वास्तव में चाहता हूं वह IProgress<Object> का कार्यान्वयन करना है जिसमें मैं बी को बुला रहा हूं, कि कॉलिंग कोड और IProgress<Object> कार्यान्वयन के बीच एक दृश्य डिस्कनेक्ट कम है। (मैं अपने प्रगति के कार्यान्वयन को एक निजी, गैर-साझा कॉलिंग विधि के प्रकार के रूप में समझने पर विचार करता हूं और इस प्रकार मैं IProgress<Object> के कार्यान्वयन को पूरी तरह से एक पूरी कक्षा के पूरी तरह से अलग तरीके से नहीं करना चाहता)।

method in class A { 
... 
Action<Object> Report = (m) => { // do something useful with m }; 

B(Report) 
} 

method B(IProgress<Object> reporter) { 
    reporter.Report(some object) 
} 
बेशक

, मुझे पता है:

मैं क्या करने की कोशिश कर रहा है एक लैम्ब्डा जिसमें मैं तो निपटने मेरी कम प्रगति को परिभाषित है, और का उपयोग किसी भी तरह इस तरह, बी को इस लैम्ब्डा पारित है यह क्यों काम नहीं करेगा - बी एक ऑब्जेक्ट चाहता है जो IProgress<Object> लागू करता है और मैं इसे इसके बजाय एक क्रिया ऑब्जेक्ट सौंप रहा हूं।

क्या हासिल करने का प्रयास करने का कोई तरीका है? (आईई मेरी कार्यान्वयन अगर IProgress<Object> विधि एक के अंदर दिखाई देते हैं?

+2

सी # lambdas गुमनाम प्रतिनिधियों हैं

यह उदाहरण अपनी परियोजना पृष्ठ से है । आपको जो चाहिए वह एक अज्ञात प्रकार है जो इंटरफ़ेस लागू करता है। सी # प्रदान करता है जो केवल सार्वजनिक-गुणों के अज्ञात प्रकारों पर कुछ कामकाज के लिए [इस सवाल] (http://stackoverflow.com/questions/191013/can-a-c-sharp-anonymous-class-implement-an-interface) देखें। –

उत्तर

11

प्रतिनिधि इंटरफेस (सीधे) लागू नहीं कर सकते हैं।

दो अच्छा विकल्प दिमाग में आते हैं:

  1. विधि बदलें कि आप एक प्रतिनिधि के प्रकार के बजाय एक IProgress प्रकार लेने के लिए कॉल कर रहे हैं की परिभाषा। (यदि संभव हो तो यह बेहतर विकल्प होगा)

  2. एक नया प्रकार बनाएं जो आपको आवश्यक इंटरफ़ेस लागू करता है और उस कार्यक्षमता को लागू करने के लिए पैरामीटर के रूप में प्रतिनिधि को लेता है।

और # 2 का उदाहरण है, जबकि इंटरफेस पर निर्भर है, कुछ इस तरह दिख सकता है:

B(new LambdaProgress<Object>(obj => ...)); 
1

मानते हुए अपने IProgress<object> इंटरफेस सिर्फ एक void Report(object) विधि है, और है कि आप एपीआई नियंत्रित करते हैं, तो आप बस तरीकों कि वर्तमान में करने के लिए प्रकार IProgress<object> की एक पैरामीटर की आवश्यकता को फिर से परिभाषित कर सकता है , और अधिक जटिल इंटरफेस के लिए

method in class A { 
... 
Action<Object> Report = (m) => { // do something useful with m }; 

B(Report) 
} 

method B(ProgressReportDelegate reporter) { 
    reporter(someObject); 
} 

:

public delegate void ProgressReportDelegate(object someObject); 

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

4

:

interface IProgress<T> 
{ 
    void doStuff(T param); 
} 

class LambdaProgress<T> : IProgress<T> 
{ 
    Action<T> action; 
    public LambdaProgress(Action<T> action) 
    { 
     this.action = action; 
    } 

    public void doStuff(T param) 
    { 
     action(param); 
    } 
} 

तो आप की तरह कुछ करने के लिए सक्षम होगा नहीं, जब इंटरफ़ेस की आवश्यकता होती है तो आप लैम्ब्डा की आपूर्ति नहीं कर सकते हैं।
लेकिन आप impromptu-interface का उपयोग कर एक अज्ञात वस्तु की आपूर्ति कर सकते हैं।

//Anonymous Class 
var anon = new 
{ 
    Prop1 = "Test", 
    Prop2 = 42L, 
    Prop3 = Guid.NewGuid(), 
    Meth1 = Return<bool>.Arguments<int>(it => it > 5) 
} 

var myInterface = anon.ActLike<IMyInterface>(); 

अपने उदाहरण में यह हो सकता है:

A 
{ 
    // Create an anonymous object. 
    var anonymous = new 
    { 
     // Define a method that needs an "object" parameter and returns nothing. 
     Report = Return.Arguments<object>(m => 
     { 
      // Do whatever you want to do when Report is called. 
     }) 
    } 

    // Get your anonymous object as an IProgress<Object>. 
    var obj = anonymous.ActLike<IProgress<Object>> 

    // Call B. 
    B(obj); 
} 
0

.NET 4.5 के साथ आप उपयोग कर सकते हैं Progress वर्ग