2016-08-02 25 views
5

क्या किसी फ़ंक्शन को इस तरीके से परिभाषित करना संभव है कि यह मूल रूप से प्रतिनिधि के रूप में स्वयं को लौटाता है?फ़ंक्शन लौटने वाले फ़ंक्शन को वापस करने के लिए फ़ंक्शन,

उदाहरण के लिए, अगर यह मान्य सिंटैक्स था:

public class Scrub 
{ 
    public NotNull NotNull<T>(T value, string name) 
    { 
     if (value == null) throw new ArgumentNullException(name); 
     return NotNull; 
    } 
} 

तो मैं कर सकता श्रृंखला विधि एक साथ इस तरह कहता है।

Scrub.NotNull(param1, nameof(param1))(param2, nameof(param2)(param3, nameof(param3)); 

उत्तर

14

खैर हां, तो आप , अपने खुद के प्रतिनिधि घोषणा के साथ कर सकते हैं:

delegate SelfReturner<T> SelfReturner<T>(T value, string name); 

static SelfReturner<T> NotNull<T>(T value, string name) 
{ 
    if (value == null) throw new ArgumentNullException(name); 
    return NotNull; 
} 

... लेकिन यह उपयोगी मुझे नहीं लगता है। तीन अलग-अलग कॉल करने के बजाय, आप वास्तव में ऐसा करना चाहते हैं? उदाहरण के लिए, मेरे पास Preconditions.CheckNotNull है जो गैर-शून्य मान देता है - मुझे लगता है कि यह दिखने से बहुत अधिक उपयोगी है, ईमानदार होना।

जैसा कि टिप्पणियों में उल्लेख किया गया है, उपर्युक्त केवल तभी काम करता है जब सभी पैरामीटर एक ही प्रकार के होते हैं (या सभी पहले पैरामीटर के प्रकार के लिए पूरी तरह से परिवर्तनीय)।

public sealed class NullChecker 
{ 
    public static NullChecker Instance { get; } = new NullChecker(); 
    private NullChecker() {} 

    public static NullChecker Scrub<T>(T value, string paramName) where T : class 
    { 
     if (value == null) 
     { 
      throw new ArgumentNullException(paramName); 
     } 
     return this; 
    } 
} 

के रूप में प्रयोग करें:

NullChecker.Instance.Scrub(param1, nameof(param1)) 
        .Scrub(param2, nameof(param2)) 
        .Scrub(param3, nameof(param3)); 

दो अलग-अलग तरीकों, एक स्थिर और एक के साथ एक वैकल्पिक एक बिट अधिक काम के साथ चेनिंग एक सामान्य विधि के साथ एक सिंगलटन उदाहरण उपयोग करने के लिए किया जाएगा अनुमति देने के लिए नहीं (लेकिन विभिन्न नामों के साथ) आप Instance भाग को हटा सकते हैं। उदाहरण के लिए:

public static class Scrub 
{ 
    public static T NotNull<T, U>(this T value, U property, string name) 
    { 
     if (property == null) throw new ArgumentNullException(name); 
     return value; 
    } 
} 

आप कर सकते हैं::

test.NotNull(test.A, nameof(testA.A).NotNull(test.B, nameof(testA.B))); 

आप नहीं काफी क्या चाहता था

NullChecker.Scrub(param1, nameof(param1)) 
      .And(param2, nameof(param2)) 
      .And(param3, nameof(param3)); 
+0

लेकिन यदि 'param1' एक स्ट्रिंग था तो यह केवल तभी काम करेगा जब' param2', 'param3', ... तार भी थे, है ना? –

+0

मैं वास्तव में उत्सुक था अगर यह वास्तव में किसी भी चीज़ से अधिक संभव था। – adam0101

+1

@IanMercer: आह हाँ, आप सही हैं। मुझे यकीन नहीं है कि इसे ठीक करना आसान है - शायद एक सिंगलटन विधि होना बेहतर होगा। इसे इंगित करने के लिए संपादित करेंगे। –

1

आप इसे एक विस्तार विधि करते हैं।

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