2012-06-13 7 views
11

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

मैं जिस प्रक्रिया के माध्यम से चला गया, उसके माध्यम से चलता हूं।

पहले, मैं एक स्थिर वर्ग तो जैसे DbExtensions नामित में अपने प्रोजेक्ट के लिए एक विस्तार विधि कहा:

'System.Data.IDbConnection' has no applicable method named 'Query' but appears to have an extension method by that name. Extension methods cannot be dynamically dispatched. Consider casting the dynamic arguments or calling the extension method without the extension method syntax.

:

using System.Collections.Generic; 
using System.Data; 
using System.Linq; 

public static class DbExtensions 
{ 
    public static T Scalar<T>(
     this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null) 
    { 
     var ret = cnn.Query<T>(sql, param as object, transaction, buffered, commandTimeout, commandType).First(); 
     return ret; 
    } 
} 

यह निम्नलिखित विवरण के साथ एक संकलन त्रुटि बनाता है

यह ठीक है, और त्रुटि वास्तव में सहायक है क्योंकि यह मुझे यह भी बताती है कि इसे कैसे ठीक किया जाए। तो मैं फिर कोशिश करता हूं:

using System.Collections.Generic; 
using System.Data; 
using System.Linq; 

public static class DbExtensions 
{ 
    public static T Scalar<T>(
     this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null) 
    { 
     var ret = SqlMapper.Query<T>(cnn, sql, param, transaction, buffered, commandTimeout, commandType).First(); 
     return ret; 
    } 
} 

और यह सही ढंग से संकलित करता है। यद्यपि कुछ अजीब चल रहा है। विजुअल स्टूडियो में, यदि मैं SqlMapper.Query<T> का वापसी मान लेता हूं जो IEnumerable<T> हो, और मैं इसे संचालित करने का प्रयास करता हूं, तो विजुअल स्टूडियो मुझे object के माध्यम से विरासत में छोड़कर कोई इंटेलिजेंस गुण नहीं देता है।

सोच रहा हूं कि मैं कुछ ऐसा कर रहा हूं जो इंटेलिजेंस समझने के लिए पर्याप्त स्मार्ट नहीं है, मैं अपने मजेदार तरीके से जाता हूं ... जब तक कि मैं वास्तव में कोड को चलाने की कोशिश नहीं करता।

जब मैं इसे चलाने के लिए प्रयास करते हैं, यह यात्राएं, जहां मैं निम्न त्रुटि के साथ .First() बोल रहा हूँ:

'System.Collections.Generic.List<MyNameSpace.MyClass>' does not contain a definition for 'First'

अब यह त्रुटि, मैंने सोचा कि दिलचस्प था ... एक के लिए मेरे सिर की पिटाई करने के बाद जबकि, मुझे एहसास हुआ कि पहला तर्क गतिशील टाइपिंग के बारे में शिकायत कर रहा था ...

मुझे लगता है कि यह त्रुटि उत्पन्न हो रही है क्योंकि संकलक जेनेरिक टेम्पलेट नहीं बना सकता क्योंकि यह नहीं जानता कि क्वेरी IEnumerable<T> लौट रही है क्योंकि इसे निष्पादित किया जा रहा है डीएलआर? मुझे किसी को यह समझाने में खुशी होगी कि यह जानकार था।

  • एक IEnumerable<T>

using System.Collections.Generic; 
using System.Data; 
using System.Linq; 

public static class DbExtensions 
{ 
    public static T Scalar<T>(
     this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null) 
    { 
     var ret = SqlMapper.Query<T>(cnn, sql, param as object, transaction, buffered, commandTimeout, commandType).First(); 
     return ret; 
    } 
} 

using System.Collections.Generic; 
using System.Data; 
using System.Linq; 

public static class DbExtensions 
{ 
    public static T Scalar2<T>(
     this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null) 
    { 
     var ret = ((IEnumerable<T>)SqlMapper.Query<T>(cnn, sql, param, transaction, commandTimeout, commandType)).First(); 
     return ret; 
    } 
} 
के लिए एक object
  • करने के लिए कास्ट dynamic परम कास्ट दिए गए मान: मैं अनिवार्य रूप से यह तय करने के लिए दो तरीके पाया है

    सारांश में:

    मैं डीएलआर के क्विकक्स के माध्यम से काम करने के लिए नया हूं और गतिशील + जेनेरिक के साथ गड़बड़ करते समय कुछ चेतावनियों को ध्यान में रखना प्रतीत होता है ...?

    मुझे पता है कि यह एक प्रश्न नहीं है, लेकिन जब मैंने वास्तव में यह लिखना शुरू किया, मुझे नहीं पता था कि क्या हो रहा था और मैंने इसे प्रक्रिया में समझ लिया! मैंने सोचा कि यह इसी तरह के मुद्दों हालांकि साथ किसी और को मदद कर सकता है ...

  • +0

    [विस्तार विधि और सी # में गतिशील वस्तु] के संभावित डुप्लिकेट (http://stackoverflow.com/questions/5311465/extens आयन-विधि-और-गतिशील-ऑब्जेक्ट-इन-सी-तेज) –

    +0

    यह कमाल है, लेकिन ध्यान दें कि स्वयं उत्तर वाले प्रश्नों के लिए सम्मेलन आदर्श रूप से प्रश्न पोस्ट करने और अलग से जवाब देने के लिए आदर्श है। – McGarnagle

    +0

    @dbaseman धन्यवाद। मैंने एक अलग उत्तर लिखा लेकिन स्पष्ट रूप से मेरे पास 8 घंटे बीतने तक "आत्म-जवाब" के लिए पर्याप्त अंक नहीं हैं: पी –

    उत्तर

    11

    के रूप में सुझाव दिया, मैं कोशिश करूँगा और उत्तर एक वास्तविक जवाब में मेरे सवाल ... (अब जब कि यह 8 घंटे हो चुके हैं)

    मेरे मुद्दे की समझ यह है:

    • referenced question में वर्णित है, गतिशील प्रकार विस्तार उन्हें उपलब्ध तरीकों की जरूरत नहीं है, लेकिन विस्तार तरीकों सामान्य रूप से इस्तेमाल किया जा सकता (उदाहरण तरीके के रूप में), बस के रूप में वे हो सकता है बिना this कीवॉयर घ ...
    उदाहरण के लिए

    : - किसी मंगलाचरण एक गतिशील तर्क यह होगा अगर जहां

    dynamic list = someListObject; 
    
    var item = list.First(); //this will not compile 
    
    var item = Enumerable.First(list); //this will compile 
    

    के रूप में जॉन स्कीट this answer में बताया गया है कि यह सब डीएलआर कार्यान्वयन के डिजाइन और भाग कर रहा है एक वापसी प्रकार गतिशील माना जाता है।

    • इसी तरह के कारणों के लिए, विस्तार के तरीकों में गतिशील चरों का उपयोग करने के लिए ऊपर के उदाहरण काम आप निम्न में से एक कर सकते हैं थोड़ा wonky है ...

    public static Enumerable<T> ExtensionMethod(this ExtendedObject p1, dynamic p2) { 
        //Do Stuff 
    } 
    
    dynamic y = something; 
    var x = new ExtendedObject(); 
    
    //this works 
    var returnedEnumerable = x.ExtensionMethod(y); 
    
    //this doesn't work 
    var returnedValue = x.ExtensionMethod(y).SomeEnumerableExtensionMethodLikeFirst() 
    

    :

    //cast dynamic as object 
    var returnedValue = x.ExtensionMethod(y as object).First(); 
    //cast returned object 
    var returnedValue = ((IEnumerable<KnownType>)x.ExtensionMethod(y)).First(); 
    
    +0

    यह केवल तभी काम करता है यदि आप वास्तविक प्रकार (जैसे विस्तारित ऑब्जेक्ट) पर डाला गया। ऑब्जेक्ट को कास्ट करना इस के लिए काम नहीं करता है। –

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