2009-01-15 10 views
6

यह मेरे अन्य प्रश्न में उल्लिखित था और मैंने सोचा कि यह रिकॉर्ड में जोड़ने के लिए उपयोगी हो सकता है। निम्नलिखित प्रोग्राम में, स्थानीय रूप से परिभाषित प्रतिनिधियों के कौन सा, यदि कोई है, तो प्रत्येक बार स्क्रैच से बनाए जाने के बजाय कार्य विधि में कॉल के बीच कैश किया जाता है?कौन सा (यदि कोई है) स्थानीय रूप से परिभाषित प्रतिनिधियों को विधि कॉल के बीच कैश किया जाता है?

namespace Example 
{ 
    class Dummy 
    { 
     public int age; 
    } 

    class Program 
    { 
     private int field = 10; 

     static void Main(string[] args) 
     { 
      var p = new Program(); 

      while (true) 
      { 
       p.Work(); 
      } 
     } 

     void Work() 
     { 
      int local = 20; 

      Action a1 =() => Console.WriteLine(field); 
      Action a2 =() => Console.WriteLine(local); 
      Action a3 =() => Console.WriteLine(this.ToString()); 
      Action a4 =() => Console.WriteLine(default(int)); 
      Func<Dummy, Dummy, bool> dummyAgeMatch = (l, r) => l.age == r.age; 

      a1.Invoke(); 
      a2.Invoke(); 
      a3.Invoke(); 
      a4.Invoke(); 
      dummyAgeMatch.Invoke(new Dummy() { age = 1 }, new Dummy(){ age = 2 }); 
     } 
    } 
} 

उत्तर

7

क्या परावर्तक शो के आधार पर, पिछले दो (a4 और dummyAgeMatch) ("सीएस $ <> 9_CachedAnonymousMethodDelegate6" "सीएस $ <> 9_CachedAnonymousMethodDelegate5" और में बुलाया क्षेत्रों में एमएस सी # 3.0 संकलक द्वारा कैश कर रहे हैं मेरा विशेष निर्माण)।

ये कैश किए जा सकते हैं, जबकि स्पष्ट रूप से अन्य कब्जे वाले चर पर निर्भर करते हैं।

मुझे विश्वास नहीं है कि व्यवहार spec द्वारा अनिवार्य है, लेकिन मोनो कंपाइलर वैसे ही व्यवहार करता है (विभिन्न परिवर्तनीय नामों के साथ)।

5

ठीक है, विशिष्ट प्रश्न का उत्तर देने के लिए: अंतिम दो केवल कैश किए गए हैं, क्योंकि वे कुछ भी कैप्चर नहीं करते हैं। आप इसे परावर्तक में देख सकते हैं (लेकिन यह सुंदर नहीं है)। बेशक, आप उन्हें उन्हें फिर से प्रयोग करने योग्य बनाने के लिए परिवर्तित कर सकते हैं आर्ग में पास करके:

Action<Program> a1 = p => Console.WriteLine(p.field); 
Action<int> a2 = i => Console.WriteLine(i); 
Action<Program> a3 = p => Console.WriteLine(p.ToString()); 
Action a4 =() => Console.WriteLine(default(int)); 
Func<Dummy, Dummy, bool> dummyAgeMatch = (l, r) => l.age == r.age; 

और a2 में a1/a3, और local में this गुजरती हैं। क्योंकि उनमें से कोई भी सीधे कुछ भी कैप्चर नहीं करता है, इसलिए वे सभी को कम से कम CS$<>9__CachedAnonymousMethodDelegate9 के माध्यम से कैश किया जा सकता है (CS$<>9__CachedAnonymousMethodDelegate5)। बेशक, वे फिर (पहले कब्जा कर लिया गया) वैरिएबल फिर से असाइन करने की क्षमता खो देते हैं, लेकिन एफपी वकालत करने वालों को वैसे भी पसंद नहीं होगा ;- आप हमेशा अद्यतन मूल्य को रिटर्न वैल्यू के रूप में पास कर सकते हैं, या एक प्रतिनिधि प्रकार घोषित कर सकते हैं ref तर्कों के साथ (हालांकि, मैं इसकी अनुशंसा नहीं करता हूं)।

+0

धन्यवाद - यह उपन्यास है! – xyz

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