c# - पैरामीटर नाम को प्रतिबिंबित करना: सी#लैम्ब्डा अभिव्यक्तियों या सिंटेक्स प्रतिभा का दुरुपयोग?




asp.net-mvc lambda (14)

मैं MvcContrib ग्रिड घटक देख रहा हूं और मैं ग्रिड सिंटैक्स में उपयोग की जाने वाली एक वाक्य रचनात्मक चाल द्वारा, एक ही समय में MvcContrib हूं,

.Attributes(style => "width:100%")

उपरोक्त वाक्यविन्यास जेनरेट किए गए HTML की शैली विशेषता को width:100% सेट करता है width:100% । अब यदि आप ध्यान देते हैं, 'शैली' कहीं भी निर्दिष्ट नहीं है, अभिव्यक्ति में पैरामीटर के नाम से लिया जाता है! मुझे इसमें खोदना पड़ा और पाया कि 'जादू' कहां होता है:

   Hash(params Func<object, TValue>[] hash)
   {
     foreach (var func in hash)
     {
       Add(func.Method.GetParameters()[0].Name, func(null));
     }
   }

तो वास्तव में, कोड औपचारिक, संकलित समय, विशेषता नाम-मूल्य जोड़े के शब्दकोश बनाने के लिए पैरामीटर का नाम उपयोग कर रहा है। नतीजतन वाक्यविन्यास निर्माण वास्तव में बहुत अभिव्यक्तिपूर्ण है, लेकिन साथ ही बहुत खतरनाक है। लैम्ब्डा अभिव्यक्तियों का सामान्य उपयोग साइड इफेक्ट के बिना इस्तेमाल किए गए नामों के प्रतिस्थापन के लिए अनुमति देता है। मुझे एक पुस्तक में एक उदाहरण दिखाई देता है जो collection.ForEach(book => Fire.Burn(book)) कहता है। collection.ForEach(book => Fire.Burn(book)) मुझे पता है कि मैं अपने कोड collection.ForEach(log => Fire.Burn(log)) में लिख सकता हूं। प्रत्येक collection.ForEach(log => Fire.Burn(log)) और इसका मतलब है बात लेकिन यहां एमवीसी कोंट्रिब ग्रिड सिंटैक्स के साथ अचानक मुझे वह कोड मिलता है जो सक्रिय रूप से दिखता है और मेरे चर के लिए चुने गए नामों के आधार पर निर्णय करता है!

तो सी # 3.5 / 4.0 समुदाय और लैम्ब्डा अभिव्यक्ति प्रेमियों के साथ यह आम अभ्यास है? या एक दुष्ट चाल है जो मुझे चिंता नहीं करनी चाहिए?


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

यह लेखक द्वारा एक ही लाभ के लिए प्रयास करने का प्रयास है जो डीएसएल आपको देता है - जब कोड सिर्फ "जैसा दिखता है" जैसा आप कहने की कोशिश कर रहे हैं, तो आप जादुई जगह पर पहुंच गए हैं। आप बहस कर सकते हैं कि यह इंटरऑप के लिए अच्छा है, या क्या यह "जटिलता" लागत को उचित ठहराने के लिए अज्ञात तरीकों से पर्याप्त अच्छा है या नहीं। काफी उचित ... इसलिए आपकी परियोजना में आपको इस तरह के वाक्यविन्यास का उपयोग करने का सही विकल्प बनाना चाहिए। लेकिन फिर भी ... यह प्रोग्रामर द्वारा दिन के अंत में क्या करने का एक चालाक प्रयास है, हम सभी ऐसा करने की कोशिश कर रहे हैं (चाहे हम इसे महसूस करें या नहीं)। और हम सब क्या करने की कोशिश कर रहे हैं, यह है: "कंप्यूटर को बताएं कि हम भाषा में क्या करना चाहते हैं जो जितना संभव हो उतना करीब है कि हम क्या सोचना चाहते हैं इसके बारे में सोचते हैं।"

कंप्यूटर पर हमारे निर्देशों को व्यक्त करने के करीब पहुंचने के साथ-साथ हम सोचते हैं कि आंतरिक रूप से सॉफ़्टवेयर को अधिक बनाए रखने योग्य और अधिक सटीक बनाने की कुंजी है।

संपादित करें: मैंने कहा था "सॉफ़्टवेयर को अधिक रखरखाव करने योग्य और अधिक सटीक बनाने की कुंजी", जो कि पागलपन से बेकार है। मैंने इसे "एक कुंजी" में बदल दिया।


आईएमएचओ, यह करने का एक अच्छा तरीका है। हम सभी इस तथ्य से प्यार करते हैं कि एक वर्ग नियंत्रक नामकरण इसे एमवीसी में एक नियंत्रक बना देगा? ऐसे में ऐसे मामले हैं जहां नामकरण महत्वपूर्ण है।

इसके अलावा इरादा यहां बहुत स्पष्ट है। यह समझना बहुत आसान है। .Attribute( book => "something") परिणामस्वरूप book="something" और .Attribute( log => "something") परिणामस्वरूप log="something"

मुझे लगता है कि यदि आप इसे एक सम्मेलन की तरह मानते हैं तो यह कोई समस्या नहीं होनी चाहिए। मेरा मानना ​​है कि जो कुछ भी आपको कम कोड लिखता है और इरादा स्पष्ट करता है वह एक अच्छी बात है।


कोड बहुत चालाक है, लेकिन यह संभावित रूप से हल होने वाली अधिक समस्याओं का कारण बनता है।

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

बेहतर समाधान होगा कि डेटा सदस्य होना चाहिए जिसे संकलित समय पर चेक किया जा सके। तो इसके बजाय:

.Attributes(style => "width:100%");

एक स्टाइल प्रॉपर्टी के साथ कोड को कंपाइलर द्वारा चेक किया जा सकता है:

.Attributes.Style = "width:100%";

या और भी:

.Attributes.Style.Width.Percent = 100;

कोड के लेखकों के लिए यह और अधिक काम है, लेकिन यह दृष्टिकोण सी # की मजबूत प्रकार की जांच क्षमता का लाभ उठाता है, जो कि बग को कोड में पहली जगह में आने से रोकने में मदद करता है।


क्या मैं इसका उपयोग एक वाक्यांश बनाने के लिए कर सकता हूं?

जादू लैम्ब्डा (एन): एक लैम्बडा फ़ंक्शन पूरी तरह से जादू स्ट्रिंग को बदलने के उद्देश्य से उपयोग किया जाता है।


निम्नलिखित में क्या गलत है:

html.Attributes["style"] = "width:100%";

बस मेरी राय में फेंकना चाहता था (मैं एमवीसी कोंट्रिब ग्रिड घटक का लेखक हूं)।

यह निश्चित रूप से भाषा दुरुपयोग है - इसके बारे में कोई संदेह नहीं है। हालांकि, मैं वास्तव में इसे सहज समझने पर विचार नहीं करता - जब आप Attributes(style => "width:100%", @class => "foo") पर कॉल देखते हैं Attributes(style => "width:100%", @class => "foo")
मुझे लगता है कि यह स्पष्ट है कि क्या हो रहा है (यह निश्चित रूप से अनाम प्रकार दृष्टिकोण से भी बदतर नहीं है)। एक इंटेलिजेंस परिप्रेक्ष्य से, मैं मानता हूं कि यह सुंदर अपारदर्शी है।

रुचि रखने वालों के लिए, MvcContrib में इसके उपयोग पर कुछ पृष्ठभूमि जानकारी ...

मैंने इसे ग्रिड में व्यक्तिगत वरीयता के रूप में जोड़ा - मुझे अज्ञात प्रकारों का उपयोग शब्दकोश के रूप में पसंद नहीं है (एक पैरामीटर जो "ऑब्जेक्ट" लेता है, उतना ही अपारदर्शी है जितना पैराम फंक []) लेता है और शब्दकोश संग्रह प्रारंभकर्ता है बल्कि वर्बोज़ (मैं वर्बोज़ धाराप्रवाह इंटरफेस का प्रशंसक भी नहीं हूं, उदाहरण के लिए एक विशेषता ("शैली", "प्रदर्शन: कोई नहीं") पर एकाधिक कॉल को एक साथ जोड़ना। विशेषता ("कक्षा", "foo") आदि)

यदि सी # शब्दकोष शब्दकोषों के लिए कम वर्बोज़ सिंटैक्स था, तो मैं ग्रिड घटक में इस वाक्यविन्यास सहित परेशान नहीं होता :)

मैं यह भी इंगित करना चाहता हूं कि एमवीसी कोंट्रिब में इसका उपयोग पूरी तरह से वैकल्पिक है - ये एक्सटेंशन विधियां हैं जो ओवरलोड को लपेटती हैं जो इसके बजाय आईडीकी लेती हैं। मुझे लगता है कि यह महत्वपूर्ण है कि यदि आप इस तरह की एक विधि प्रदान करते हैं तो आपको अन्य 'सामान्य' दृष्टिकोण का समर्थन करना चाहिए, उदाहरण के लिए अन्य भाषाओं के साथ इंटरऑप करना।

इसके अलावा, किसी ने 'प्रतिबिंब ओवरहेड' का उल्लेख किया और मैं बस यह इंगित करना चाहता था कि वास्तव में इस दृष्टिकोण के साथ अधिकतर ओवरहेड नहीं है - इसमें कोई रनटाइम प्रतिबिंब या अभिव्यक्ति संकलन शामिल नहीं है ( http://blog.bittercoder.com/PermaLink,guid,206e64d1-29ae-4362-874b-83f5b103727f.aspx देखें http://blog.bittercoder.com/PermaLink,guid,206e64d1-29ae-4362-874b-83f5b103727f.aspx )।


मुझे लगता है कि यह "जादू तार" से बेहतर नहीं है। मैं इसके लिए अज्ञात प्रकार के प्रशंसक नहीं हूं। इसे एक बेहतर और दृढ़ता से टाइप किए गए दृष्टिकोण की आवश्यकता है।


मेरी राय में यह भेड़ के बच्चे का दुरुपयोग है।

वाक्यविन्यास प्रतिभा के रूप में मुझे style=>"width:100%" सादा भ्रमित लगता है। विशेष रूप से => बजाय => की वजह से


मैं चाहूंगा की

Attributes.Add(string name, string value);

यह अधिक स्पष्ट और मानक है और लैम्ब्स का उपयोग करके कुछ भी प्राप्त नहीं किया जा रहा है।


मैं शायद ही कभी इस तरह के उपयोग में आया था। मुझे लगता है कि यह "अनुचित" है :)

यह उपयोग का एक आम तरीका नहीं है, यह सामान्य सम्मेलनों के साथ असंगत है। इस प्रकार के वाक्यविन्यास में पेशेवरों और विपक्ष हैं:

विपक्ष

  • कोड अंतर्ज्ञानी नहीं है (सामान्य सम्मेलन अलग हैं)
  • यह नाजुक हो जाता है (पैरामीटर का नाम कार्यक्षमता तोड़ देगा)।
  • परीक्षण करना थोड़ा मुश्किल है (एपीआई को पकाने के लिए परीक्षणों में प्रतिबिंब के उपयोग की आवश्यकता होगी)।
  • अगर अभिव्यक्ति का व्यापक रूप से उपयोग किया जाता है तो यह पैरामीटर का विश्लेषण करने की आवश्यकता के कारण धीमा हो जाएगा, न केवल मूल्य (प्रतिबिंब लागत)

पेशेवरों

  • इस वाक्यविन्यास में समायोजित डेवलपर के बाद यह अधिक पठनीय है।

नीचे की रेखा - सार्वजनिक एपीआई डिजाइन में मैं अधिक स्पष्ट तरीका चुना होगा।


यह अभिव्यक्ति पेड़ों के लाभों में से एक है - कोई भी अतिरिक्त जानकारी के लिए कोड की जांच कर सकता है। यही है। .Where(e => e.Name == "Jamie") समकक्ष एसक्यूएल में परिवर्तित किया जा सकता है जहां खंड। यह अभिव्यक्ति पेड़ों का एक चालाक उपयोग है, हालांकि मुझे आशा है कि यह इससे आगे नहीं जायेगा। कुछ और जटिल जटिल कोड की तुलना में अधिक कठिन होने की संभावना है, इसलिए मुझे संदेह है कि यह स्वयं सीमित होगा।


यह एक दिलचस्प दृष्टिकोण है। यदि आपने अभिव्यक्ति के दाईं ओर केवल स्थिरांक होने के लिए बाध्य किया है तो आप इसका उपयोग कर कार्यान्वित कर सकते हैं

Expression<Func<object, string>>

जो मुझे लगता है वह वास्तव में प्रतिनिधि के बजाय आप चाहते हैं (आप दोनों पक्षों के नाम प्राप्त करने के लिए लैम्ब्डा का उपयोग कर रहे हैं) नीचे बेवकूफ कार्यान्वयन देखें:

public static IDictionary<string, string> Hash(params Expression<Func<object, string>>[] hash) {
    Dictionary<string, string> values = new Dictionary<string,string>();
    foreach (var func in hash) {
        values[func.Parameters[0].Name] = ((ConstantExpression)func.Body).Value.ToString();
    }
    return values;
}

यह थ्रेड में पहले उल्लेख किया गया क्रॉस भाषा इंटरऑप चिंता का भी पता लगा सकता है।


रेल भूमि में आपका स्वागत है :)

जब तक आप जानते हैं कि क्या हो रहा है, तब तक इसमें वास्तव में कुछ भी गलत नहीं है। (यह तब होता है जब इस तरह की चीज अच्छी तरह से प्रलेखित नहीं होती है कि कोई समस्या है)।

रेल ढांचे की पूरी तरह कॉन्फ़िगरेशन पर सम्मेलन के विचार पर बनाई गई है। चीजों का नामकरण एक निश्चित तरीके से आपको एक ऐसे सम्मेलन में चाबियाँ देता है जिसका उपयोग आप कर रहे हैं और आपको मुफ्त में पूरी तरह से कार्यक्षमता मिलती है। नामकरण सम्मेलन के बाद आपको वह स्थान मिल जाता है जहां आप तेजी से जा रहे हैं। पूरी बात शानदार ढंग से काम करती है।

एक और जगह जहां मैंने इस तरह की चाल देखी है, मोक में विधि कॉल दावे में है। आप एक लैम्ब्डा में गुजरते हैं, लेकिन लैम्ब्डा कभी निष्पादित नहीं होता है। वे यह सुनिश्चित करने के लिए अभिव्यक्ति का उपयोग करते हैं कि विधि कॉल हुआ और यदि अपवाद नहीं है तो उसे अपवाद फेंक दें।


वास्तव में यह रूबी की तरह लगता है =), कम से कम मेरे लिए बाद में गतिशील "लुकअप" के लिए एक स्थिर संसाधन का उपयोग एपीआई डिजाइन विचारों के लिए उपयुक्त नहीं है, उम्मीद है कि यह चालाक चाल उस एपीआई में वैकल्पिक है।

हम IDictionary (या नहीं) से प्राप्त कर सकते हैं और एक इंडेक्सर प्रदान करते हैं जो एक php सरणी की तरह व्यवहार करता है जब आपको कोई मान सेट करने के लिए कोई कुंजी जोड़ने की आवश्यकता नहीं होती है। यह .NET semantics का वैध उपयोग नहीं होगा, केवल c #, और अभी भी दस्तावेज़ की आवश्यकता है।

उम्मीद है की यह मदद करेगा





mvccontrib