C # 4.0 में 'डायनामिक' प्रकार किसके लिए प्रयोग किया जाता है?


236

C # 4.0 ने एक नया प्रकार पेश किया जिसे 'डायनामिक' कहा जाता है। यह सब अच्छा लगता है, लेकिन एक प्रोग्रामर इसका क्या उपयोग करेगा?

क्या ऐसी स्थिति है जहां यह दिन बचा सकता है?



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


मुझे उम्मीद है कि इस लेख में आपके प्रश्न का पूरा उत्तर है visualstudiomagazine.com/Articles/2011/02/01/…
डेवलपर

जवाबों:


196

गतिशील कीवर्ड C # 4.0 के लिए नया है, और इसका उपयोग कंपाइलर को बताने के लिए किया जाता है कि एक चर का प्रकार बदल सकता है या यह कि रनटाइम तक ज्ञात नहीं है। इसे किसी कास्ट के बिना इंटरेक्ट करने में सक्षम समझें।

dynamic cust = GetCustomer();
cust.FirstName = "foo"; // works as expected
cust.Process(); // works as expected
cust.MissingMethod(); // No method found!

ध्यान दें कि हमें ग्राहक के रूप में कास्ट करने और न ही कस्टडी घोषित करने की आवश्यकता थी। क्योंकि हमने इसे गतिशील घोषित किया था, रनटाइम खत्म हो गया और फिर हमारे लिए FirstName संपत्ति खोजता है और सेट करता है। अब, निश्चित रूप से, जब आप एक गतिशील चर का उपयोग कर रहे हैं, तो आप संकलक प्रकार की जाँच छोड़ रहे हैं। इसका अर्थ है कॉल कस्ट.मिसिंगमेथोड () संकलन और रनटाइम तक विफल नहीं होगा। इस ऑपरेशन का परिणाम एक RuntimeBinderException है क्योंकि MissingMethod ग्राहक वर्ग पर परिभाषित नहीं है।

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

dynamic foo = 123;
foo = "bar";

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

decimal foo = GetDecimalValue();
foo = foo / 2.5; // Does not compile
foo = Math.Sqrt(foo); // Does not compile
string bar = foo.ToString("c");

दूसरी लाइन संकलित नहीं करती है क्योंकि 2.5 को डबल के रूप में टाइप किया जाता है और लाइन 3 को संकलित नहीं किया जाता है क्योंकि Math.Sqrt एक डबल की अपेक्षा करता है। जाहिर है, आपको बस इतना करना है और अपने वैरिएबल टाइप को कास्ट और / या बदलना है, लेकिन ऐसी परिस्थितियां भी हो सकती हैं, जहां डायनामिक उपयोग करने के लिए समझ में आता है।

dynamic foo = GetDecimalValue(); // still returns a decimal
foo = foo / 2.5; // The runtime takes care of this for us
foo = Math.Sqrt(foo); // Again, the DLR works its magic
string bar = foo.ToString("c");

और अधिक पढ़ें सुविधा: http://www.codeproject.com/KB/cs/CSharp4Features.aspx


96
व्यक्तिगत रूप से मैं dynamicc # सुविधाओं के समाधान के लिए c # के उपयोग के बारे में सोचता हूं जो मानक c # सुविधाओं और स्थिर टाइपिंग द्वारा हल किया जा सकता है (शायद इससे भी बेहतर) या टाइप इंट्रेंस के साथ ( var)। इसका उपयोग केवल तब किया dynamicजाना चाहिए जब यह DLR के साथ इंटरऑपरेबिलिटी मुद्दों पर आता है। यदि आप एक स्थिर टाइप की गई भाषा में कोड लिखते हैं, जैसे c # है, तो इसे करें, और न ही डायनेमिक भाषा का अनुकरण करें। बस बदसूरत है।
फिलिप ड्यूमेयर

40
यदि आप dynamicअपने कोड में चर का भारी उपयोग करते हैं, जहां आपको उनकी आवश्यकता नहीं है (जैसे कि आपके उदाहरण में स्क्वररूट) तो आप क्लीन कंपाइल टाइम एरर चेकिंग छोड़ देते हैं; इसके बजाय अब आप संभावित रनटाइम त्रुटियाँ प्राप्त कर रहे हैं।
फिलिप डबमीयर

33
ज्यादातर ठीक है, लेकिन एक जोड़ी छोटी त्रुटियां। सबसे पहले, यह कहना सही नहीं है कि गतिशील का मतलब है कि चर का प्रकार बदल सकता है। विचाराधीन चर प्रकार "गतिशील" है (सी # भाषा के परिप्रेक्ष्य से; सीएलआर के दृष्टिकोण से चर प्रकार का है)। एक चर का प्रकार कभी नहीं बदलता है। किसी चर के मान का रनटाइम प्रकार, चर के प्रकार के साथ संगत किसी भी प्रकार का हो सकता है। (या संदर्भ प्रकारों के मामले में, यह अशक्त हो सकता है।)
एरिक लिपर्ट

15
अपने दूसरे बिंदु के बारे में: C # में पहले से ही "एक वैरिएबल बना सकते हैं जिसे आप कुछ भी डाल सकते हैं" की विशेषता है - आप हमेशा प्रकार की वस्तु का एक चर बना सकते हैं। डायनामिक के बारे में दिलचस्प बात यह है कि आप अपने पहले पैराग्राफ में क्या इंगित करते हैं: डायनेमिक ऑब्जेक्ट के समान है, सिवाय इसके कि सिमेंटिक विश्लेषण को रनटाइम तक स्थगित कर दिया जाता है, और सिमेंटिक विश्लेषण रनटाइम प्रकार की अभिव्यक्ति पर किया जाता है। (अधिकतर। कुछ अपवाद हैं।)
एरिक लिपर्ट

18
मैंने इस पर एक प्रमुख बिंदु बिताया है, मुख्यतः क्योंकि यह सामान्य रूप से कीवर्ड के उपयोग की वकालत कर रहा है। इसका एक विशेष रूप से लक्षित उद्देश्य है (लस्स के उत्तर में पूरी तरह से वर्णित है) और हालांकि यह उत्तर बिल्कुल-सही है, यह डेवलपर्स को भटकने की संभावना है।
आठ-बिट गुरु

211

dynamicकीवर्ड भी जुड़ गया, एक साथ सी # 4.0 के कई अन्य नई सुविधाओं के साथ, यह सरल कोड से बात करने के बनाने के लिए है कि में जीवन या अन्य runtimes, अलग एपीआई है से आता है।

एक उदाहरण लीजिए।

यदि आपके पास एक COM ऑब्जेक्ट है, जैसे Word.Applicationऑब्जेक्ट, और एक दस्तावेज़ खोलना चाहते हैं, तो ऐसा करने की विधि 15 से कम मापदंडों के साथ नहीं आती है, जिनमें से अधिकांश वैकल्पिक हैं।

इस पद्धति को कॉल करने के लिए, आपको कुछ इस तरह की आवश्यकता होगी (मैं सरल कर रहा हूं, यह वास्तविक कोड नहीं है):

object missing = System.Reflection.Missing.Value;
object fileName = "C:\\test.docx";
object readOnly = true;
wordApplication.Documents.Open(ref fileName, ref missing, ref readOnly,
    ref missing, ref missing, ref missing, ref missing, ref missing,
    ref missing, ref missing, ref missing, ref missing, ref missing,
    ref missing, ref missing);

उन सभी तर्कों पर ध्यान दें? आपको संस्करण 4.0 से पहले C # के बाद से पास करने की आवश्यकता है, जिसमें वैकल्पिक तर्कों की धारणा नहीं है। C # 4.0 में, COM API को शुरू करने के साथ काम करना आसान बना दिया गया है:

  1. वैकल्पिक तर्क
  2. refCOM API के लिए वैकल्पिक बनाना
  3. नामित तर्क

उपरोक्त कॉल के लिए नया सिंटैक्स होगा:

wordApplication.Documents.Open(@"C:\Test.docx", ReadOnly: true);

देखें कि यह कितना आसान लगता है, यह कितना अधिक पठनीय बन जाता है?

चलो इसे तोड़ दो:

                                    named argument, can skip the rest
                                                   |
                                                   v
wordApplication.Documents.Open(@"C:\Test.docx", ReadOnly: true);
                                 ^                         ^
                                 |                         |
                               notice no ref keyword, can pass
                               actual parameter values instead

जादू यह है कि सी # संकलक अब आवश्यक कोड को इंजेक्ट करेगा, और रनटाइम में नई कक्षाओं के साथ काम करेगा, लगभग वही काम करने के लिए जो आपने पहले किया था, लेकिन सिंटैक्स आपसे छिपा हुआ है, अब आप इस पर ध्यान केंद्रित कर सकते हैं क्या , और कैसे पर इतना नहीं । एंडर्स हेजेलबर्ग यह कहने के शौकीन हैं कि आपको अलग-अलग "भस्म" का आह्वान करना होगा, जो कि पूरी चीज़ के जादू पर एक प्रकार का दंड है, जहां आपको आमतौर पर अपना हाथ लहराना होता है और सही क्रम में कुछ जादू शब्द बोलना होता है। एक निश्चित प्रकार की वर्तनी प्राप्त करने के लिए। COM ऑब्जेक्ट्स से बात करने का पुराना एपीआई तरीका बहुत कुछ था, आपको कोड को संकलित करने के लिए संकलक को सहलाने के लिए बहुत सारे हुप्स के माध्यम से कूदने की आवश्यकता थी।

संस्करण 4.0 से पहले सी # में चीजें टूट जाती हैं यदि आप किसी COM ऑब्जेक्ट से बात करने की कोशिश करते हैं, जिसके लिए आपके पास कोई इंटरफ़ेस या क्लास नहीं है, तो आपके पास एक IDispatchसंदर्भ है।

यदि आप नहीं जानते कि यह क्या है, IDispatchतो मूल रूप से COM वस्तुओं के लिए प्रतिबिंब है। एक IDispatchइंटरफ़ेस के साथ आप ऑब्जेक्ट से पूछ सकते हैं "सहेजें के रूप में ज्ञात विधि के लिए आईडी नंबर क्या है", और तर्क मान वाले एक निश्चित प्रकार के सरणियों का निर्माण करें, और अंत में Invokeविधि IDispatchको कॉल करने के लिए इंटरफ़ेस पर एक विधि को कॉल करें, सभी पासिंग वह सूचना जिसे आपने एक साथ करने में कामयाब रहे हैं।

उपरोक्त सहेजें विधि इस तरह दिख सकती है (यह निश्चित रूप से सही कोड नहीं है):

string[] methodNames = new[] { "Open" };
Guid IID = ...
int methodId = wordApplication.GetIDsOfNames(IID, methodNames, methodNames.Length, lcid, dispid);
SafeArray args = new SafeArray(new[] { fileName, missing, missing, .... });
wordApplication.Invoke(methodId, ... args, ...);

यह सब सिर्फ एक दस्तावेज खोलने के लिए।

VB के पास लंबे समय पहले इस बॉक्स के अधिकांश के लिए वैकल्पिक तर्क और समर्थन थे, इसलिए यह C # कोड:

wordApplication.Documents.Open(@"C:\Test.docx", ReadOnly: true);

मूल रूप से अभिव्यक्ति के संदर्भ में VB को केवल C # पकड़ रहा है, लेकिन इसे सही तरीके से कर रहा है, इसे विस्तार योग्य बनाकर, और सिर्फ COM के लिए नहीं। बेशक यह VB.NET या .NET रनटाइम के शीर्ष पर निर्मित किसी अन्य भाषा के लिए भी उपलब्ध है।

आप IDispatchइंटरफ़ेस के बारे में अधिक जानकारी विकिपीडिया: IDispatch पर प्राप्त कर सकते हैं यदि आप इसके बारे में अधिक पढ़ना चाहते हैं। यह वास्तव में सामान है।

हालांकि, क्या होगा अगर आप एक पायथन ऑब्जेक्ट से बात करना चाहते हैं? COM ऑब्जेक्ट्स के लिए उपयोग किए जाने वाले एक से अधिक के लिए एक अलग API है, और चूंकि पायथन ऑब्जेक्ट प्रकृति में गतिशील हैं, इसलिए आपको कॉल करने के लिए सही तरीके, उनके मापदंडों आदि को खोजने के लिए जादू का सहारा लेने की आवश्यकता है, लेकिन .NET नहीं। प्रतिबिंब, पायथन के लिए कुछ लिखा गया है, ऊपर दिए गए IDispatch कोड की तरह ही, बिल्कुल अलग।

और रूबी के लिए? एक अलग एपीआई अभी भी।

जावास्क्रिप्ट? समान सौदा, उसके लिए भी अलग एपीआई।

डायनामिक कीवर्ड में दो चीज़ें होती हैं:

  1. C # में नया कीवर्ड, dynamic
  2. रनटाइम कक्षाओं का एक सेट जो जानता है कि विभिन्न प्रकार की वस्तुओं से कैसे निपटना है, जो एक विशिष्ट एपीआई को लागू करता है जिसे dynamicकीवर्ड की आवश्यकता होती है, और कॉल को चीजों को करने के सही तरीके से मैप करता है। एपीआई को भी प्रलेखित किया गया है, इसलिए यदि आपके पास ऐसी वस्तुएं हैं जो एक रनटाइम से आती हैं, तो आप इसे जोड़ नहीं सकते हैं।

dynamicकीवर्ड नहीं है, तथापि, किसी भी मौजूदा नेट-केवल कोड की जगह के लिए है। निश्चित रूप से, आप इसे कर सकते हैं, लेकिन इसे इस कारण से नहीं जोड़ा गया था, और फ्रंट में एंडर्स हेजलबर्ग के साथ सी # प्रोग्रामिंग भाषा के लेखक, सबसे अधिक अडिग रहे हैं कि वे अभी भी सी # को एक जोरदार टाइप की हुई भाषा मानते हैं, और बलिदान नहीं करेंगे वह सिद्धांत।

इसका मतलब है कि यद्यपि आप इस तरह कोड लिख सकते हैं:

dynamic x = 10;
dynamic y = 3.14;
dynamic z = "test";
dynamic k = true;
dynamic l = x + y * z - k;

और यह संकलित है, यह जादू-चलो-आंकड़ा-आउट-क्या-आप-मतलब-पर-रनटाइम प्रकार की प्रणाली के रूप में नहीं था।

संपूर्ण उद्देश्य अन्य प्रकार की वस्तुओं से बात करना आसान बनाना था।

इंटरनेट पर कीवर्ड, प्रस्तावकों, विरोधियों, चर्चा, शेख़ी, प्रशंसा, आदि के बारे में बहुत सारी सामग्री है।

मेरा सुझाव है कि आप निम्न लिंक से शुरू करते हैं और फिर अधिक के लिए Google:


12
यह वेब JSON एपीआई के लिए COM से अलग भी उपयोगी है जहां डे-धारावाहिक JSON ऑब्जेक्ट्स की संरचना C # में निर्दिष्ट नहीं है। उदाहरण के लिए System.Web.Helpers.Json का डिकोड विधि एक गतिशील वस्तु देता है
dumbledad

एक तरफ "वे अभी भी सी # को एक दृढ़ता से टाइप की गई भाषा के रूप में मानते हैं": एरिक लिपर्ट विवरण के रूप में "दृढ़ता से टाइप किए गए" के प्रशंसक नहीं हैं
एंड्रयू कीटन

मैं उससे असहमत हूं, लेकिन यह एक विचार का विषय है, तथ्य का नहीं। मेरे लिए "दृढ़ता से टाइप" का मतलब है कि संकलनकर्ता जानता है, संकलन समय पर, किस प्रकार का उपयोग किया जाता है, और इस प्रकार उन प्रकारों के आसपास निर्धारित नियमों को लागू करता है। यह तथ्य कि आप एक डायनेमिक प्रकार का विकल्प चुन सकते हैं जो नियम की जाँच करता है और रनटाइम के लिए बाइंडिंग मेरे लिए नहीं है, इसका मतलब है कि भाषा कमजोर रूप से टाइप की गई है। मैं आमतौर पर विपरीत रूप से कमजोर टाइप करने के लिए दृढ़ता से टाइप नहीं करता हूं, हालांकि, मैं आमतौर पर इसे डायनामिक रूप से टाइप किया जाता हूं, जैसे कि पायथन जैसी भाषाएं, जहां सब कुछ डक होता है।
लास वी। कार्लसन

इस जवाब का क्या मतलब है? इसका आधा वैकल्पिक मापदंडों और IDispatch इंटरफ़ेस के बारे में है।
ज़म

इसीलिए dynamicजोड़ा गया था कि कैसे परावर्तन जैसी विधि के लिए अन्य पारिस्थितिक तंत्रों का समर्थन किया जा सकता है, साथ ही इसे प्राप्त करने के दस्तावेज तरीके के साथ डेटा संरचनाओं को एक प्रकार का ब्लैक बॉक्स दृष्टिकोण प्रदान किया जाता है।
लास वी। कार्लसन

29

मुझे आश्चर्य है कि किसी ने कई प्रेषण का उल्लेख नहीं किया । इसके चारों ओर काम करने का सामान्य तरीका विज़िटर पैटर्न के माध्यम से है और यह हमेशा संभव नहीं होता है इसलिए आप स्टैक्ड हो जाते हैंis चेक के ।

तो यहाँ मेरे खुद के आवेदन का एक वास्तविक जीवन उदाहरण है। करने के बजाय:

public static MapDtoBase CreateDto(ChartItem item)
{
    if (item is ElevationPoint) return CreateDtoImpl((ElevationPoint)item);
    if (item is MapPoint) return CreateDtoImpl((MapPoint)item);
    if (item is MapPolyline) return CreateDtoImpl((MapPolyline)item);
    //other subtypes follow
    throw new ObjectNotFoundException("Counld not find suitable DTO for " + item.GetType());
}

तुम करो:

public static MapDtoBase CreateDto(ChartItem item)
{
    return CreateDtoImpl(item as dynamic);
}

private static MapDtoBase CreateDtoImpl(ChartItem item)
{
    throw new ObjectNotFoundException("Counld not find suitable DTO for " + item.GetType());
}

private static MapDtoBase CreateDtoImpl(MapPoint item)
{
    return new MapPointDto(item);
}

private static MapDtoBase CreateDtoImpl(ElevationPoint item)
{
    return new ElevationDto(item);
}

ध्यान दें कि पहले मामले ElevationPointमें उप-वर्ग है MapPointऔर अगर इसे पहले नहीं रखा गया है तो यह MapPointकभी भी नहीं पहुंचेगा। यह गतिशील के साथ ऐसा नहीं है, क्योंकि निकटतम मिलान विधि को बुलाया जाएगा।

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


इस उपयोग के मामले के बारे में नहीं पता था। एक बिट hacky सबसे अच्छा, हालांकि। यह किसी भी स्थिर विश्लेषक को फेंक देगा।
कुगेल

2
@Kugel जो सच है, लेकिन मैं इसे हैक नहीं कहूंगा । स्थैतिक विश्लेषण अच्छा है, लेकिन मैं इसे एक सुरुचिपूर्ण समाधान से नहीं रोक सकता, जहां विकल्प हैं: खुले-बंद सिद्धांत का उल्लंघन (विज़िटर पैटर्न) या isएक के ऊपर एक खूंखार स्टैक्ड के साथ साइक्लोमैटिक जटिलता बढ़ गई ।
स्टेलियोस एडमांटीडिस

4
वैसे आपके पास C # 7 के साथ पैटर्न मिलान का विकल्प है, नहीं?
कुगेल

2
अच्छी तरह से ऑपरेटर बहुत कम खर्चीले हैं, इस तरह से (डबल कास्ट से बचने के लिए) और आपको स्थैतिक विश्लेषण वापस ;-) और प्रदर्शन मिलता है।
कुगेल

@idbrii कृपया मेरे उत्तर न बदलें। एक टिप्पणी छोड़ने के लिए स्वतंत्र महसूस करें और मैं स्पष्ट कर दूंगा (यदि आवश्यक हो) क्योंकि मैं अभी भी इस समुदाय में सक्रिय हूं। इसके अलावा, कृपया उपयोग न करें magic; जादू जैसी कोई चीज नहीं है।
स्टेलियोस एडमांटीडिस

11

डीएलआर (गतिशील भाषा रनटाइम) पर चलने वाले, गतिशील लोगों (अजगर, रूबी ...) के साथ संभोग करने के लिए स्थिर टाइप की गई भाषाओं (सीएलआर) के लिए यह आसान बनाता है : MSDN देखें :

उदाहरण के लिए, आप XML में C # में काउंटर बढ़ाने के लिए निम्न कोड का उपयोग कर सकते हैं।

Scriptobj.SetProperty("Count", ((int)GetProperty("Count")) + 1);

DLR का उपयोग करके, आप एक ही ऑपरेशन के लिए निम्नलिखित कोड का उपयोग कर सकते हैं।

scriptobj.Count += 1;

MSDN इन लाभों को सूचीबद्ध करता है:

  • .NET फ्रेमवर्क में डायनामिक लैंग्वेज को पोर्ट करना सरल करता है
  • स्टैटिकली टाइप की गई भाषाओं में डायनामिक फीचर्स सक्षम करता है
  • DLR और .NET फ्रेमवर्क के भविष्य के लाभ प्रदान करता है
  • लाइब्रेरीज़ और ऑब्जेक्ट्स को साझा करना सक्षम करता है
  • फास्ट डायनेमिक डिस्पैच और इनवोकेशन प्रदान करता है

अधिक विवरण के लिए MSDN देखें ।


1
और गतिशील के लिए आवश्यक VM को बदलने के लिए वह वास्तव में गतिशील भाषाओं को आसान बनाता है।
डायकम

2
@ डीकम: वीएम में कोई बदलाव नहीं हुआ है। DLR .NET 2.0 में सभी तरह से ठीक काम करता है।
जोर्ग डब्ल्यू मित्तग

@ Jörg, हाँ एक बदलाव है। DLR आंशिक रूप से फिर से लिखा जाता है क्योंकि यह अब VM ने गतिशील समाधान के समर्थन में बनाया है।
डायकम

मैं थोड़ा बहुत आशावादी था, अनुसंधान से पता चला कि परिवर्तन इतने बड़े नहीं थे।
डायकम

4

उपयोग का एक उदाहरण:

आप कई वर्गों का उपभोग करते हैं जिनके पास एक सांप्रदायिक संपत्ति है 'क्रिएशनडेट':

public class Contact
{
    // some properties

    public DateTime CreationDate { get; set; }        
}

public class Company
{
    // some properties

    public DateTime CreationDate { get; set; }

}

public class Opportunity
{
    // some properties

    public DateTime CreationDate { get; set; }

}

यदि आप एक सांप्रदायिक विधि लिखते हैं, जो 'क्रिएशनडेट' संपत्ति का मान प्राप्त करता है, तो आपको प्रतिबिंब का उपयोग करना होगा:

    static DateTime RetrieveValueOfCreationDate(Object item)
    {
        return (DateTime)item.GetType().GetProperty("CreationDate").GetValue(item);
    }

'गतिशील' अवधारणा के साथ, आपका कोड बहुत अधिक सुरुचिपूर्ण है:

    static DateTime RetrieveValueOfCreationDate(dynamic item)
    {
        return item.CreationDate;
    }

7
बतख टाइपिंग, अच्छा हालाँकि आपको इसके लिए एक इंटरफ़ेस का उपयोग करना चाहिए यदि वे आपके प्रकार हैं।
कुगेल


2

इसका उपयोग कोड गुणवत्ता, इंटेलीजेंसी को नष्ट करने और टाइम बग डिटेक्शन को संकलित करने के लिए ज्यादातर राड और पायथन पीड़ितों द्वारा किया जाएगा ।


एक सनकी जवाब लेकिन आसानी से सच भी है। मैंने इसे केवल परिणाम के साथ संरचनाओं की घोषणा से बचने के लिए देखा है कि कोड काम करता है यदि सब कुछ ठीक है, लेकिन जैसे ही आप इसे स्थानांतरित करते हैं, तो इसके स्टैक को अप्रत्याशित तरीके से उड़ा देता है।
एंथनीवीओ

हाँ, आप उस क्लासिक कोने को बहुत सी अन्य भाषा सुविधाओं के साथ काटते हुए देखेंगे। यह कोई आश्चर्य की बात नहीं है कि आप इसे यहाँ भी देखेंगे।
हॉकआई 4040

1

यह रनटाइम पर मूल्यांकन करता है, जिससे आप जावास्क्रिप्ट में अपने इच्छित प्रकार को स्विच कर सकते हैं। यह कानूनी है:

dynamic i = 12;
i = "text";

और इसलिए आप आवश्यकता के अनुसार प्रकार बदल सकते हैं। इसे अंतिम उपाय के रूप में उपयोग करें; यह फायदेमंद है, लेकिन मैंने सुना है कि उत्पन्न आईएल के संदर्भ में दृश्यों के तहत बहुत कुछ होता है और यह एक प्रदर्शन मूल्य पर आ सकता है।


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

6
ज़रूर, लेकिन यह "गतिशील" के बजाय "वस्तु" के साथ "वैध" रहा होगा। आपने यहां डायनामिक के बारे में कुछ भी दिलचस्प नहीं दिखाया है।
एरिक लिपर्ट

ऑब्जेक्ट के लिए, आपको इसे उपयुक्त प्रकार में डालना होगा, वास्तव में इसके किसी भी तरीके को लागू करने के लिए ... आप हस्ताक्षर खो देते हैं; आप संकलित त्रुटि के बिना किसी भी विधि से अपना कोड कॉल कर सकते हैं, और यह रनटाइम में त्रुटियां करता है। टाइप करने की जल्दी में था, निर्दिष्ट नहीं करने के लिए क्षमा करें। और @Lasse, मैं सहमत हूँ और मैं शायद गतिशील ज्यादा का उपयोग नहीं करेंगे।
ब्रायन मेन्स

1
अंतिम उपाय उपयोग के मामले की व्याख्या नहीं की गई है
denfromufa

1

मेरे लिए 'डायनेमिक' प्रकार के चर का सबसे अच्छा उपयोग तब हुआ था, जब हाल ही में, मैं ADO.NET ( SQLDataReader का उपयोग करके ) में एक डेटा एक्सेस लेयर लिख रहा था और कोड पहले से ही लिखित विरासत संग्रहित प्रक्रियाओं को लागू कर रहा था। व्यापार तर्क के थोक युक्त उन विरासत संग्रहित प्रक्रियाओं के सैकड़ों हैं। मेरे डेटा एक्सेस लेयर को कुछ हेरफेर करने के लिए, बिजनेस लॉजिक लेयर, C # आधारित, को कुछ प्रकार के संरचित डेटा को वापस करने की आवश्यकता होती है ( हालांकि लगभग कोई भी नहीं हैं )। प्रत्येक संग्रहीत कार्यविधियाँ डेटा के अलग सेट ( टेबल कॉलम ) लौटाती हैं । इसलिए लौटे हुए डेटा को रखने और उसे BLL में पास करने के लिए दर्जनों कक्षाएं या स्ट्रक्चर्स बनाने के बजाय, मैंने नीचे दिया गया कोड लिखा, जो काफी सुरुचिपूर्ण और साफ-सुथरा दिखता है।

public static dynamic GetSomeData(ParameterDTO dto)
        {
            dynamic result = null;
            string SPName = "a_legacy_stored_procedure";
            using (SqlConnection connection = new SqlConnection(DataConnection.ConnectionString))
            {
                SqlCommand command = new SqlCommand(SPName, connection);
                command.CommandType = System.Data.CommandType.StoredProcedure;                
                command.Parameters.Add(new SqlParameter("@empid", dto.EmpID));
                command.Parameters.Add(new SqlParameter("@deptid", dto.DeptID));
                connection.Open();
                using (SqlDataReader reader = command.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        dynamic row = new ExpandoObject();
                        row.EmpName = reader["EmpFullName"].ToString();
                        row.DeptName = reader["DeptName"].ToString();
                        row.AnotherColumn = reader["AnotherColumn"].ToString();                        
                        result = row;
                    }
                }
            }
            return result;
        }

0
  1. आप अजगर की तरह गतिशील भाषाओं में कॉल कर सकते हैं जैसे CPython:

dynamic np = Py.Import("numpy")

  1. आप उन dynamicपर संख्यात्मक ऑपरेटरों को लागू करते समय जेनरिक कास्ट कर सकते हैं। यह प्रकार की सुरक्षा प्रदान करता है और जेनरिक की सीमाओं से बचता है। यह सार में है * बतख टाइपिंग:

T y = x * (dynamic)x, कहाँ पे typeof(x) is T


0

dynamicटाइपिंग के लिए एक और उपयोग का मामला आभासी तरीकों के लिए है जो कोवरियन या कंट्रोवर्सी के साथ समस्या का अनुभव करते हैं। ऐसा ही एक उदाहरण कुख्यात Cloneतरीका है जो उसी प्रकार की वस्तु को लौटाता है जिस तरह की वस्तु को कहा जाता है। यह समस्या पूरी तरह से एक गतिशील रिटर्न के साथ हल नहीं होती है क्योंकि यह स्थैतिक प्रकार की जाँच को दरकिनार कर देती है, लेकिन कम से कम आपको सादे का उपयोग करते समय हर समय बदसूरत कलाकारों का उपयोग करने की आवश्यकता नहीं होती है object। अन्यथा कहने के लिए, जातियां अंतर्निहित हो जाती हैं।

public class A
{
    // attributes and constructor here
    public virtual dynamic Clone()
    {
        var clone = new A();
        // Do more cloning stuff here
        return clone;
    }
}

public class B : A
{
    // more attributes and constructor here
    public override dynamic Clone()
    {
        var clone = new B();    
        // Do more cloning stuff here
        return clone;
    }
}    

public class Program
{
    public static void Main()
    {
        A a = new A().Clone();  // No cast needed here
        B b = new B().Clone();  // and here
        // do more stuff with a and b
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.