2009-03-02 14 views
20

मैं एक सामान्य जो करने के लिए मैं एक पैरामीटर के रूप में एक समारोह पारित कर सकते हैं बनाना चाहते हैं, लेकिन इस समारोह मापदंडों ही तो ... शामिल हो सकते हैंपैरामीटर के रूप में एक फ़ंक्शन (पैरामीटर के साथ) पास करना?

int foo = GetCachedValue("LastFoo", methodToGetFoo) 

इस तरह की है कि:

protected int methodToGetFoo(DateTime today) 
{ return 2; // example only } 

अनिवार्य रूप से मैं चाहता हूँ एक विधि है जो कैश को किसी मान के लिए जांच करेगी, अन्यथा पास की गई विधि के आधार पर मान उत्पन्न करेगी।

विचार?

+0

के लिए मैं ऐसा करने के तरीके पता नहीं है, लेकिन एक नोट के रूप में, इस सवाल का जहाँ तक मैं बता सकता हूँ जेनरिक के साथ कोई लेना देना नहीं लगता है। – recursive

+0

यह तरह का, थोड़ा सा, शायद। शायद "प्रतिनिधि" को "जेनेरिक" को प्रतिस्थापित करना चाहिए। – mquander

+0

क्षमा करें, मैं इसे संभालने के लिए एक सामान्य विधि बना रहा था, इसलिए मैंने सोचा कि यह संबंधित था। लेकिन गुजरने वास्तव में प्रतिनिधि संबंधित है, इसलिए मैं अद्यतन करूँगा। धन्यवाद – klkitchens

उत्तर

37

ऐसा लगता है कि आप एक Func<T> चाहते लगता है:

T GetCachedValue<T>(string key, Func<T> method) { 
    T value; 
    if(!cache.TryGetValue(key, out value)) { 
     value = method(); 
     cache[key] = value; 
    } 
    return value; 
} 

फोन करने वाले तो यह कई मायनों में लपेट कर सकते हैं;

int i = GetCachedValue("Foo", GetNextValue); 
... 
int GetNextValue() {...} 

या जहां तर्क शामिल कर रहे हैं, एक बंद: सरल कार्यों के लिए

var bar = ... 
int i = GetCachedValue("Foo",() => GetNextValue(bar)); 
+1

धन्यवाद मैं बहुत करीब था, लेकिन यह समझ में नहीं आया कि जेनेरिक में सीधे पैरा कैसे प्राप्त करें।बंद करने के साथ आखिरी विकल्प कुंजी था! एक जादू की तरह काम करता है। – klkitchens

+2

वास्तव में यहां पुराना एक है लेकिन बंद करने का हिस्सा वही था जो मैं ढूंढ रहा था –

4

आप अपनी खुद की प्रतिनिधि बना सकते हैं, लेकिन सी # में 3.0 आप इसे और अधिक सुविधाजनक उपयोग करने के लिए मिल सकता है में निर्मित इस समस्या को हल करने के लिए Func<T> प्रतिनिधि परिवार। उदाहरण: एक स्ट्रिंग, एक पूर्णांक है, और एक समारोह है कि दिनांक समय लेता है और किसी पूर्णांक रिटर्न:

public int GetCachedValue(string p1, int p2, 
          Func<DateTime, int> getCachedValue) 
{ 
    // do some stuff in here 
    // you can call getCachedValue like any normal function from within here 
} 

इस विधि तीन तर्कों का समय लगेगा। उदाहरण के लिए:

int foo = GetCachedValue("blah", 5, methodToGetFoo); // using your method 
int bar = GetCachedValue("fuzz", 1, d => d.TotalDays); // using a lambda 

अलग Func<T, U, V...> आदि प्रकार के ढांचे में मौजूद तर्क के विभिन्न मात्रा के साथ तरीकों को समायोजित करने के।

3

विधि methodToGetFoo

public delegate object GenerateValue(params p); 
public event GenerateValue OnGenerateValue; 

के लिए एक प्रतिनिधि बनाएं प्रतिनिधि

int GetCachedValue(string key, GenerateValue functionToCall); 

उपयोग करने के लिए फिर OnGenerateValue के कार्यान्वयन में आप परम की जांच कर सकते हैं GetCachedValue को परिभाषित करें।

2

Here कुछ आसान है जो मैंने शुरू किया है जिसे थोड़ा आगे ले जाया जा सकता है (जैसा कि मैंने एक वाणिज्यिक परियोजना के लिए किया था)।

मेरे मामले में इस वेब सेवा कॉल कैश करने के लिए था, और की तरह कुछ इस्तेमाल किया गया था:

WebService ws = new WebService(); 
var result = ws.Call(x => x.Foo("bar", 1)); // x is the ws instance 
7

System.Action और लैम्ब्डा अभिव्यक्ति (anonimous विधि) का उपयोग करना। उदाहरण

public void myMethod(int integer){ 

    //Do something 

} 

public void passFunction(System.Action methodWithParameters){ 

    //Invoke 
    methodWithParameters(); 

} 

//... 

//Pass anonimous method using lambda expression 
passFunction(() => myMethod(1234)); 
संबंधित मुद्दे