2016-08-04 8 views
6

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

हो रहा था मैं एक बिल्डर जो एक HttpWebRequest वस्तु और HttpWebRequest पर एक विस्तार विधि देता है पर किसी भी प्रकाश डाला सकता है।

मेरे बिल्डर विधियों में से एक string तर्क लेता है। जब मैं बिल्डर विधि को एक स्ट्रिंग पास करता हूं तो पूरी चीज काम करती है, लेकिन मैं इसे dynamic वैरिएबल पास करता हूं जो एक स्ट्रिंग है जो अब काम नहीं करती है।

ऐसा लगता है कि बिल्डर्स विधि जो HttpWebRequestBuilder टाइप करना चाहिए अब dynamic लौटाता है।

नीचे कोड एक सरल यह पुन: पेश करने के लिए था और यह भी उपलब्ध है here

नोट

यह काम कर, लाइन .SetBody(dynamicString) बाहर टिप्पणी और लाइन .SetBody(json) uncomment करने के लिए।

public class Program 
{ 
    public static void Main() 
    { 
     dynamic dynamicString = "{ \"test\" : \"value\" }"; 
     string json = "{ \"test\" : \"value\" }"; 

     string test = new HttpWebRequestBuilder() 
      .SetRequestType() 
      //.SetBody(json) //uncomment this and it works 
      .SetBody(dynamicString) //uncomment this and it breaks 
      .Build() 
      .ExtensionMethod(); 

     Console.WriteLine(test); 
    } 

} 

public class HttpWebRequestBuilder 
{ 
    private readonly HttpWebRequest _request; 

    public HttpWebRequestBuilder() 
    { 
     Uri uri = new Uri("http://www.google.com"); 
     _request = WebRequest.CreateHttp(uri); 
    } 

    public HttpWebRequestBuilder SetRequestType() 
    { 
     _request.Method = "POST"; 
     _request.ContentType = "application/json"; 

     return this; 
    } 

    public HttpWebRequestBuilder SetBody(string json) 
    { 
     byte[] bytes = Encoding.UTF8.GetBytes(json); 
     _request.ContentLength = bytes.Length; 

     using (Stream writer = _request.GetRequestStream()) 
     { 
      writer.Write(bytes, 0, bytes.Length); 
      writer.Flush(); 
     } 

     return this; 
    } 

    public HttpWebRequest Build() 
    { 
     return _request; 
    } 
} 

public static class WebRequestExtensions 
{ 
    public static string ExtensionMethod(this HttpWebRequest webRequest) 
    { 
     return "extension method worked"; 
    } 
} 

मेरा अनुमान है कि यह कुछ रास्ता dynamic वस्तुओं काम के साथ अजीब है। लेकिन किसी भी स्पष्टीकरण की सराहना की जाएगी।

उत्तर

7

यह इसलिए होता है क्योंकि एक dynamic पैरामीटर गुजर, अर्थात .SetBody(dynamicString), बनाता है के रूप में dynamic (प्रासंगिक explanation of method return types with dynamic parameters) सी # संकलक अभिव्यक्ति की वापसी प्रकार का इलाज।

एक्सटेंशन तरीकों विस्तार तरीके के रूप में न केवल नियमित तरीके के रूप में dynamic वस्तुओं, (इस के लिए स्पष्टीकरण Eric Lippert's answer देखें), इसलिए संकलन समय त्रुटि है कि आप देख के साथ काम करते हैं।

+0

मैं अतीत में एरिक की है कि इसका जवाब पढ़ते हैं, लेकिन मैं पूरी तरह भूल गया इसके बारे में:/ –

1

हालांकि dasblinkenlight का जवाब सही प्रतीत हो रहा है, कृपया याद रखें कि आप हमेशा इस तरह से अपने कोड को पुन: द्वारा इस समस्या से बचने कर सकते हैं:

public class Program 
{  public static void Main() 
    { 
     dynamic dynamicString = "{ \"test\" : \"value\" }"; 
     string json = "{ \"test\" : \"value\" }"; 

     var test = new HttpWebRequestBuilder(); 
      test.SetRequestType(); 
      //test.SetBody(json); //still works 
      test.SetBody(dynamicString); // works also now 
      var b = test.Build(); 
      var s = b.ExtensionMethod(); 

     Console.WriteLine(s); 
    } 
} 
+0

इसके लिए धन्यवाद, मैंने वास्तव में परीक्षण किया था जब मैं परीक्षण करने के आसपास कुछ ऐसा किया था। सवाल यह समझने के लिए और अधिक था कि यह क्यों हो रहा था। यह किसी और के लिए सहायक हो सकता है इसलिए मैं एक +1 छोड़ दूंगा – Dreagen

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