2015-10-14 8 views
10

के रूप में अभिव्यक्ति स्वीकार करता है मैं .NET4.5 और C# उपयोग कर रहा हूँ मैं विस्तार विधि बनाने अनुमान है कि मुझे वस्तु की संपत्ति पारित करने के लिए अनुमति होगी और यदि उस वस्तु की पहचान 0 है तो return null अन्यथा कि संपत्ति के मूल्य वापसी।एक्सटेंशन विधि है कि अभिव्यक्ति <Func<T>> पैरामीटर

मैं इसे प्रतिबिंब के साथ कोई समस्या नहीं कर सकता था इसलिए इस प्रशिक्षण अभ्यास पर विचार करें और मैं वास्तविक समस्या को हल करने की कोशिश नहीं कर रहा हूं।

वर्तमान में विस्तार विधि static कक्षा में बैठा है इस तरह लग रही:

public static object GetNullIfNotSet(this WillAnswer answer, Expression<Func<WillAnswer>> expression) 
    { 
     if (answer.Id == 0) return null; 
     return expression.Compile()(); 
    } 

तरह से मैं इसका इस्तेमाल करने में सक्षम होना चाहते है निम्नलिखित (उत्तर प्रकार WillAnswer की है):

var emptyIfNewObject = answer.GetNullIfNotSet(o => o.HasBusinessAssets) 

हालांकि यह मुझे संकलन त्रुटि देता है:

Error 1 Delegate 'System.Func' does not take 1 arguments C:\hg\Website\Areas\Wills\ViewModel\Answers.cs 38 59 Website enter image description here

जो मुझे फहराता है क्योंकि मुझे नहीं लगता कि मैं कोई तर्क पारित कर रहा हूं (क्या मैं?)। कृपया मुझे समझाने की तुलना में किसी को समझदार हो सकता है कि मेरी कौन सी अपेक्षाएं गलत हैं।

बस अगर मैं स्पष्ट नहीं था तो मैं दोहरा दूंगा। मैं चाहता हूं कि var emptyIfNewObject = answer.GetNullIfNotSet(o => o.HasBusinessAssets) पर कॉल करें और null प्राप्त करें यदि Idanswer0 है।

+1

दूसरों के रूप में ने बताया है, आपको अभिव्यक्ति की आवश्यकता नहीं है। आपकी त्रुटि का स्रोत तथ्य यह है कि आपने अपना func गलत परिभाषित किया है।आप शायद कुछ Func <ऑब्जेक्ट, WillAnswer> (ऑब्जेक्ट रिटर्न प्रकार होने के साथ) चाहते हैं। –

+1

इसे इस तरह से कॉल करें: 'answer.GetNullIfNotSet (() => (((Func ) (() => answer.HasBusinessAssets))()));' क्या गड़बड़ है! haim770 के उत्तर पर वापस जाएं :-) –

+0

यदि आपके पास उस ऑब्जेक्ट तक पहुंच है, जिस पर आप उस विधि को एक्सेस करते हैं जब आप विधि को कॉल करते हैं, जो आप करते हैं क्योंकि यह ऑब्जेक्ट पर एक एक्सटेंशन है, तो क्यों न केवल संपत्ति को पास करें एक 'Func'? – user2697817

उत्तर

14

Expression के लिए कोई ज़रूरत नहीं बिल्कुल, बस Func<WillAnswer, TProp> का उपयोग करें:

public static TProp GetNullIfNotSet<TProp>(this WillAnswer answer, Func<WillAnswer, TProp> func) 
{ 
    if (answer.Id == 0) return default(TProp); 
    return func(answer); 
} 

कृपया ध्यान दें कि यह हमेशा null वापस नहीं होगा, लेकिन डिफ़ॉल्ट मान (मामले में संपत्ति एक मूल्य की तरह है)।

अद्यतन (आपके अनुरोध के अनुसार):

आदेश पारित संपत्तियों के लिए null लौटने में सक्षम होने के लिए, विधि हस्ताक्षर बजाय object वापस जाने के लिए बदल गया था:

public static object GetNullIfNotSet<TProp>(this WillAnswer answer, Func<WillAnswer, TProp> func) 
{ 
    if (answer.Id == 0) return null; 
    return func(answer); 
} 

लेकिन, आप जेनेरिक के लाभ खो देंगे और आप Nullable<T>:

var emptyIfNewObject = (bool?)answer.GetNullIfNotSet(o => o.HasBusinessAssets) 
पर स्पष्ट रूप से समाप्त हो जाएंगे

जो कम आदर्श है।

+0

ग्रेट उत्तर लेकिन, मैं इसे वापस करने के लिए कैसे प्राप्त करूं? –

+0

हमेशा 'शून्य' वापस करने के लिए, कंपाइलर को यह सुनिश्चित करना होगा कि उत्तीर्ण संपत्ति 'x => x.SomeProp' एक संदर्भ प्रकार है। यह एक सामान्य बाधा जोड़कर किया जा सकता है, लेकिन इसका मतलब है कि आप 'x => x.SomeInt' (उदाहरण के लिए) वापस नहीं कर पाएंगे। क्या आपको इसकी आवश्यकता है? – haim770

+0

आप मामूली aleteration में आप 'TProp' वापसी' के बजाय का जवाब object' इस अशक्त 'जनता स्थिर वस्तु GetNullIfNotSet (इस WillAnswer जवाब है, समारोह समारोह) { अगर (उत्तर वापस जाने के लिए अनुमति देता है कर सकता है। आईडी == 0) वापस शून्य; वापसी func (उत्तर); } ' –

7

ऐसा लगता है कि आप एक अभिव्यक्ति एक Func<WillAnswer, T> नहीं की जरूरत है:

public static T GetDefaultIfNotSet<T>(this WillAnswer answer, Func<WillAnswer, T> func) { 
    if (null == answer) 
     throw new ArgumentNullException("answer"); 
    else if (null == func) 
     throw new ArgumentNullException("func"); 

    return answer.Id == 0 ? return default(T) : func(answer); 
    } 

संपादित: यदि आप करना चाहते हैं सुनिश्चितnull आप सीमित कर सकते हैं सामान्य T:

 public static T GetNullIfNotSet<T>(this WillAnswer answer, Func<WillAnswer, T> func) 
     where T: class { // no structs here 
     if (null == answer) 
      throw new ArgumentNullException("answer"); 
     else if (null == func) 
      throw new ArgumentNullException("func"); 

     return answer.Id == 0 ? return null : func(answer); 
    } 
+0

मैं 'GetDefaultIfNotSet' जैसी विधि नाम का नाम बदलने का भी सुझाव दूंगा, क्योंकि अर्थशास्त्र बदल गया है - 'bool' संपत्ति के लिए' null' मान वापस करना संभव नहीं है। –

+0

@ सेर्गेई कोलोडिया: धन्यवाद! मैंने जवाब संपादित कर लिया है, 'GetDefaultIfNotSet' एक बेहतर नाम है। –

+0

@ सेर्गेईकोलोदीय लेकिन मुझे उस शून्य की आवश्यकता है, यह प्रश्न –

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