2015-03-08 9 views
5


सी # में, लैम्ब्डा स्थानीय चर का उपयोग कर सकते हैं, और कुछ डेटा भी वापस कर सकते हैं।सी # लैम्ब्डा, स्थानीय वैरिएबल बनाम रिटर्न डेटा

तो, जो निम्न स्थितियों में बेहतर है?

int num; 
Func<int> func =()=>{return 10;} 
num = func(); 

बनाम

int num; 
Action action =()=>{num = 10;} 

मुझे लगता है, प्रदर्शन अलग है। कौन सा बेहतर है?



अद्यतन यहाँ

मेरे कोड (मैं जानता हूँ कि StackOverflow का उपयोग कैसे न)।

ErrorCode errorCode; 
errorCode = DatabaseUtility.Read<ErrorCode>(
    conn, 
    DatabaseUtility.CreateSelectQuery(....), 
    reader => 
    { 
     if(reader.Read()) 
      return ErrorCode.None; 

     return ErrorCode.InvalidParam; 
    }); 

लेकिन इस मामले में, मैं ऐसा कर सकता हूं।

ErrorCode errorCode; 
DatabaseUtility.Read(
    conn, 
    DatabaseUtility.CreateSelectQuery(....), 
    reader => 
    { 
     if(reader.Read()) 
      errorCode = ErrorCode.None; 
     else 
      errorCode = ErrorCode.InvalidParam; 
    }); 

और, यह विधि परिभाषा है।

public static class DatabaseUtility 
{ 
    public static Read<T>(
     MySqlConnection conn, 
     string query, 
     Func<MySqlDataReader, T> callback); 
} 
+1

आप क्या हासिल करने की कोशिश कर रहे हैं? _better_ से आपका क्या मतलब है? आपको '10' से' num' को सीधे निर्दिष्ट करने से क्या रोक रहा है? –

+0

@ सेल्मन 22 आप क्या पूछ रहे हैं? यह सिर्फ एक साधारण उदाहरण है। अगर आप जानना चाहते हैं कि मैं यह ज्ञान क्यों जानना चाहता हूं, तो मैं आपको बता सकता हूं। मैं अपने डीबी से कुछ डेटा चुनने का प्रयास करता हूं, और डेटा को संभालता हूं। इसके लिए, मैं Func प्रकार पैरामीटर के साथ उपयोगिता विधि परिभाषित करता हूं। और मैं उपयोगिता विधि के बाद अपना डेटा संभालता हूं, इसलिए Func मेरा डेटा वापस कर देता है। लेकिन लैम्ब्डा स्थानीय चर का उपयोग कर सकते हैं, मैं अपना डेटा क्यों वापस कर सकता हूं? मैं अपने डेटा को अपने स्थानीय चर में असाइन कर सकता हूं। यही है ना? तो मैं पूछता हूं, जो बेहतर कोड है। –

+0

आपको क्या लगता है कि प्रदर्शन अलग है? क्या आपका ऐप इतना सही है कि आपको ऐसे माइक्रो ऑप्टिमाइज़ेशन पर परेशान होना है? –

उत्तर

2

पहला एक बेहतर डिजाइन किया गया है। यह पुन: प्रयोज्य है और अलग-अलग चर (यदि आवश्यक हो) पर बार-बार कहा जा सकता है।

प्रदर्शन मुझे यकीन नहीं है, सबसे अधिक नगण्य।

+0

+1। आईएमएचओ एक अच्छी तरह से लिखित सॉफ्टवेयर थोड़ा अधिक प्रदर्शन करने वाले ब्लॉक से अधिक मूल्यवान है। आपके कोड में आप डीबी से निपटते हैं, जो आम तौर पर कुछ सी # संचालन से काफी अधिक समय लेता है। किसी भी चीज के लिए 100% वोट पढ़ने, बनाए रखने और संभवतः जीओएफ पैटर्न का पालन करना आसान है: http://en.wikipedia.org/wiki/Design_Patterns –

4

गिब्बू सही है: मान वापस करना स्पष्ट है, इसलिए आपको इसका उपयोग करना चाहिए और प्रदर्शन के बारे में चिंता न करें, जब तक कि यह कोड the 3% of code when microoptimizations make sense में न हो।

लेकिन लौटने से भी अधिक कुशल हो सकता है, क्योंकि इसे बंद करने के उद्देश्य के लिए ढेर आवंटन की आवश्यकता नहीं होती है और इसका मतलब है कि num को स्थानीय चर के रूप में संकलित किया जा रहा है, न कि बंद करने वाले ऑब्जेक्ट पर एक फ़ील्ड (स्थानीय पहुंच चर फ़ील्ड से सस्ता है)।

इसके अलावा, आप मान देने के लिए जा रहे हैं, वहाँ जो अपने कोड थोड़ा कर देगा इतनी जल्दी चर घोषित करने के लिए कोई कारण नहीं है, है कम:

Func<int> func =()=>{return 10;} 
int num = func(); 
+0

यदि मैं लैम्ब्डा में स्थानीय चर का उपयोग करता हूं, तो वैरिएबल को सदस्य चर की तरह बदल दिया गया है? मेरा अद्यतन कोड अलग नहीं है? यदि मैं एक से अधिक कोड एक से अधिक बार उपयोग करता हूं, तो लैम्ब्डा प्रत्येक बार डेटा लौटाता है, है ना? लेकिन अगर मैं एक ही स्थानीय चर (क्षेत्र बदल सकता है) तक पहुंचता हूं, तो केवल एक फ़ील्ड है। कौन सा मुझे बेहतर प्रदर्शन दिखाता है? मुझे पता है कि यह बहुत ही छोटा अंतर है। मुझे बस आश्चर्य है। –

+0

हां, आपके अपडेट किए गए कोड के साथ, यह अभी भी वही है। और यदि आप एक से अधिक बार उपयोग करते हैं, तो यह भी वही है: बंद ऑब्जेक्ट बनाना और किसी फ़ील्ड तक पहुंचना ऑब्जेक्ट बनाने और स्थानीय चर तक पहुंचने से कहीं अधिक महंगा होगा। – svick

+0

यदि मैं लैम्ब्डा पर बनाता हूं और इसे कॉल करता हूं, तो ** बंद ऑब्जेक्ट ** हर बार बनाया जाता है? यदि नहीं, तो प्रत्येक कॉल किए गए समय की ** वापसी लागत ** ** निर्मित बंद ऑब्जेक्ट ** की तुलना में अधिक महंगा है, है ना? तो, क्या मैं समझ सकता हूं कि ** बंद ऑब्जेक्ट ** हर बार बनाया जाता है जब मैं func() को फिर से कॉल करता हूं? –

1

असल में वहाँ एक बड़ा semantical अंतर है।

() => 10; 
() => x = 10; 

दोनों लौटने से 10 अंतर यह है कि दूसरे मामले में, x चर कब्जा कर लिया है, लांबा शरीर के लिए बाध्य है, और संदर्भों के माध्यम से यात्रा कर सकते हैं।

कल्पना कीजिए:

void SomeFunction() 
{ 
    int variable; 
    Execute((a) => variable = a); 
} 

void Execute(Action<int> statement) 
{ 
    statement.Invoke(7); 
} 

यहाँ SomeFunc पता नहीं क्या चर का मान जब समारोह संदर्भ से बाहर निकल रहा हो जाएगा है। दूसरी तरफ Execute को पता नहीं है कि Invoke के माध्यम से फ़ंक्शन ऑब्जेक्ट में दिए गए मान के साथ क्या होगा। यह कुछ encapsulation संदर्भों में उपयोगी हो सकता है। या संभवतः उन परिस्थितियों में जहां आपने सी # की जेनेरिक सीमाएं मारा (जो कि रास्ते से बहुत आसान है)।

तब आप अपने कोड की बात करते समय दोनों तरीकों से सोच सकते हैं। जैसे"क्या मैं अपनी तरफ से त्रुटियों को संभालना चाहता हूं, या क्या मैं त्रुटि इंटरफेस के माध्यम से अपने इंटरफेस के उपयोगकर्ता को प्रदान करता हूं?"

लेकिन फिर, मैं लैम्बडास के बजाय उपरोक्त व्यवहार को लागू/लागू करने के लिए अमूर्त वर्ग का उपयोग करना चाहता हूं।

आम तौर पर, संदर्भों पर कब्जे वाले चर भेजना निर्भरता को छिपाने लगता है और आपके कोड को पढ़ने और डीबग करने के लिए कठिन (कुछ मामलों में शायद असंभव) बनाता है। मुझे लगता है कि इसे केवल उन परिदृश्यों में उपयोग किया जाना चाहिए जहां सी # के अन्य सभी साधन या तो बहुत धीमी या बहुत बदसूरत कोड उत्पन्न करते हैं।

+0

कोई तथ्य नहीं है कि मैं वास्तव में क्या भटकता हूं। और मैं आपकी बात नहीं जानता क्योंकि मेरी अंग्रेजी खराब है। तुम्हारा मतलब लैम्ब्डा का उपयोग नहीं है? –

+0

नहीं, लैम्ब्डा का प्रयोग करें। लेकिन जरूरी या तुच्छ तक जब तक कब्जे वाले चर का उपयोग करने से बचें। –

+0

** कब्जे वाले चर ** ** लैम्ब्डा के बाहर के स्थानीय चर का मतलब है? –

1

मैं कोड आप पोस्ट के साथ एक छोटे मुद्दे को उठाने के लिए चाहते हैं:

public static class DatabaseUtility 
{ 
    public static Read<T>(
     MySqlConnection conn, 
     string query, 
     Func<MySqlDataReader, T> callback); 
} 

विधि कोई वापसी प्रकार हस्ताक्षर है! क्या यह शून्य है? यदि यह शून्य है कोड तुम्हें तैनात काम नहीं करेगा:

ErrorCode errorCode; 
errorCode = DatabaseUtility.Read<ErrorCode>(
    conn, 
    DatabaseUtility.CreateSelectQuery(....), 
    reader => 
    { 
     if(reader.Read()) 
      return ErrorCode.None; 

     return ErrorCode.InvalidParam; 
    }); 

अगर यह टी है पहले से ही फिर वहाँ एक समारोह की घोषणा करने के समारोह पढ़ने के लिए पारित करने के लिए कोई जरूरत नहीं है।

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

public static class DatabaseUtility 
{ 
    public static T Read<T>(
     MySqlConnection conn, 
     string query, 
     Action<MySqlDataReader> callback); 
} 

आधार है कि बुद्धिमान प्रदर्शन यह एक समस्या जब तक आप एक वास्तविक समय आवेदन (जो मुझे लगता है कि अपने मामले नहीं है) को लक्षित कर रहे नहीं होना चाहिए। हालांकि यह neater समाधान आईएमएचओ होगा।

उम्मीद है कि यह मदद करता है।

+0

मेरी पोस्ट में गायब वापसी प्रकार मेरी गलती है। एलोस विधि में 'वापसी कॉलबैक (MySqlDataReaderInstance) शामिल है; ' –

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