2012-05-10 17 views
7

कुछ पुनर्रचना के बाद एक दिलचस्प क्रम मुद्दा में पड़ गए और निम्न स्थिति के लिए नीचे में पिन किया हुआ है से विधि बुला जब।एक गतिशील पैरामीटर पासिंग RuntimeBinderException फेंकता विरासत में प्राप्त इंटरफ़ेस

जब एक अंतरफलक है कि एक माता पिता से विरासत में मिला दिया गया है क्रम बांधने की मशीन इंटरफेस विधि नहीं मिल रहा है पर एक पद्धति के लिए एक गतिशील वस्तु से एक संपत्ति गुजर।

यहाँ (जब सीधे विधि बुला माता पिता इंटरफ़ेस प्रकार पर) दोनों की विफलता और सफलता के प्रदर्शन में

using System.Dynamic; 
using Microsoft.CSharp.RuntimeBinder; 
using Microsoft.VisualStudio.TestTools.UnitTesting; 

namespace Test.Utility 
{ 
    public interface IEcho 
    { 
     string EchoString(string input); 
    } 

    public interface IInheritEcho : IEcho 
    { } 

    public class EchoClass : IInheritEcho 
    { 
     public string EchoString(string input) 
     { 
      return input; 
     } 
    } 

    [TestClass] 
    public class RuntimeBinderTest 
    { 
     [TestMethod] 
     public void RuntimeBinder_should_work_when_dynamic_parameters_are_passed_to_method_from_inherited_interface() 
     { 
      //Arrange 
      dynamic dynObject = new ExpandoObject(); 
      dynObject.Foo = "Bar"; 
      IInheritEcho echomore = new EchoClass(); 

      string echo = null; 
      string exceptionMessage = null; 

      //Act 
      try 
      { 
       echo = echomore.EchoString(dynObject.Foo); 
      } 
      catch (RuntimeBinderException e) 
      { 
       exceptionMessage = e.Message; 
      } 

      //Assert 
      Assert.AreEqual(echo, dynObject.Foo, false, exceptionMessage); 
     } 

     [TestMethod] 
     public void RuntimeBinder_should_work_when_dynamic_parameters_are_passed_to_method_from_noninherited_interface() 
     { 
      //Arrange 
      dynamic dynObject = new ExpandoObject(); 
      dynObject.Foo = "Bar"; 
      IEcho echomore = new EchoClass(); 

      string echo = null; 
      string exceptionMessage = null; 

      //Act 
      try 
      { 
       echo = echomore.EchoString(dynObject.Foo); 
      } 
      catch (RuntimeBinderException e) 
      { 
       exceptionMessage = e.Message; 
      } 

      //Assert 
      Assert.AreEqual(echo, dynObject.Foo, false, exceptionMessage); 
     } 
    } 
} 

टेस्ट # 1 विफल एक परीक्षण है: Assert.AreEqual विफल रहा है। अपेक्षित: < (शून्य)>। वास्तविक :. 'Test.Utility.IInheritEcho' 'EchoString'

टेस्ट # 2 में सफलता के लिए एक परिभाषा शामिल नहीं है।

मेरे सवाल यह है कि मेरी धारणा है कि 1 टेस्ट पास करना चाहिए सही है या वहाँ रूपरेखा है कि यह नहीं है में एक मौलिक कारण है?

मुझे पता है कि जब मैं उन्हें पास करता हूं या उन्हें पास करने से पहले चर को आवंटित करता हूं तो पैरामीटर कास्टिंग करके मैं समस्या को ठीक कर सकता हूं। विरासत में आने वाले इंटरफ़ेस को रनटाइम बाइंडर विफल होने के कारण मैं उत्सुक हूं। ..

+0

पर एक दस्तावेज बग आप पूरी तरह से सही हो सकता है। (हालांकि यह पुराने सी # संस्करण का है: http://msdn.microsoft.com/en-us/library/aa664578%28VS.71%29.aspx) विफलता होनी चाहिए। क्या होगा यदि आप विस्तारित ऑब्जेक्ट की बजाय स्ट्रिंग प्रॉपर्टी के साथ नियमित कक्षा का उपयोग करते हैं? क्या यह विरासत इंटरफ़ेस में विधि पाता है? (टेस्ट खुद को बनाने के लिए यहां वीएस नहीं है)। यदि यह स्थैतिक बाध्यकारी (संकलन समय बाध्यकारी) के साथ था, तो गतिशील बांधने की मशीन (रन टाइम बाइंडर) में कुछ गड़बड़ है। – JotaBe

+0

एक स्ट्रिंग प्रॉपर्टी के साथ एक नियमित कक्षा का उपयोग अपेक्षित के रूप में गुजरता है। यह निश्चित रूप से रनटाइम बांधने वाला है जो व्यवहार नहीं कर रहा है ... – piff

+0

यदि आप माइक्रोस्कोफ़ कनेक्ट के igofed के उत्तर लिंक को देखते हैं, तो यह बग knwon है और संभवतः नए वीएस संस्करण में हल नहीं किया जाएगा। – JotaBe

उत्तर

2

एक अच्छा सवाल यह।

ऐसा लगता है कि यह संकलन समय, IInheritEcho पर अभिव्यक्ति का प्रकार ले रहा है, और गतिशील रूप से आह्वान करने के तरीके की तलाश करते समय विरासत वाले इंटरफेस के सदस्यों को गहराई से खोज नहीं रहा है।

और आदर्श एक dynamic अभिव्यक्ति सी # संकलक के रूप में एक ही तरह से व्यवहार करना चाहिए के लिए सी # क्रम बांधने की मशीन - इसलिए यह देखना चाहिए कि IEcho इंटरफ़ेस IInheritEcho द्वारा विरासत में मिली है और यह काम करना चाहिए। अर्थात है कि यह स्थिर टाइपिंग है - -

हम परिकल्पना का परीक्षण कर सकते हैं पहले टेस्ट में ऐसा करने से:

echo = ((dynamic)echomore).EchoString(dynObject.Foo); 

अरे Presto - परीक्षण गुजरता है।

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

मेरी राय में इस व्यवहार सही नहीं है।

कृपया एरिक Lippert ... अच्छा ...

4

आप स्थितियों Microsoft Connect

+0

तो एक ज्ञात मुद्दा। [इस सवाल] के माध्यम से अनुसरण करता है (http://stackoverflow.com/questions/3696047/why-calling-isetdynamic-contains-compiles-but-throws-an-exception-at-runtim) जो इस मुद्दे पर एक अच्छी चर्चा है – piff

+0

एफवाईआई, किसी के लिए Google के माध्यम से इसे फिर से ढूंढने के लिए, इस बग पर माइक्रोसॉफ्ट द्वारा अंतिम निर्णय 4/6/2011 को "ठीक नहीं किया जाएगा" के कारण "ठीक नहीं होगा"। बू। :( – longda

+0

और पांच साल बाद यह अभी भी गुंजाइश से बाहर है? –

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