फ़ंक्शन पैरामीटर में "यह"


88

HtmlHelpers के लिए कुछ कोड उदाहरणों को देखते हुए, और मैं उन घोषणाओं को देखता हूं जो इस तरह दिखती हैं:

public static string HelperName(this HtmlHelper htmlHelper, ...more regular params )

मुझे यह याद नहीं है कि इस प्रकार के निर्माण को किसी और जगह पर कैसे देखा जा सकता है - क्या कोई "इस" के उद्देश्य की व्याख्या कर सकता है? मैंने सोचा था कि कुछ सार्वजनिक स्थैतिक घोषित करने से तात्पर्य यह है कि वर्ग को तत्काल करने की आवश्यकता नहीं है - इसलिए इस मामले में "यह" क्या है?

जवाबों:


212

यह एक्सटेंशन विधियों, C # 3.0 की एक नई सुविधा घोषित करने के लिए सिंटैक्स है।

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

मुझे एक उदाहरण देने दें।

स्ट्रिंग वर्ग पर कोई विधि नहीं है जिसे GobbleGobble नाम दिया गया है, तो चलिए एक विस्तार विधि बनाते हैं:

public static class StringExtensions
{
    public static void GobbleGobble(this string s)
    {
        Console.Out.WriteLine("Gobble Gobble, " + s);
    }
}

वर्ग का नाम सिर्फ मेरा नामकरण सम्मेलन है, इसे इस तरह नाम देना आवश्यक नहीं है, लेकिन इसे स्थिर करना होगा, जैसा कि विधि है।

उपरोक्त विधि घोषित करने के बाद, आप Visual Studio में, यह टाइप कर सकते हैं:

String s = "Turkey Baster!";
s.

डॉट के बाद, इंटलिसेंस के लिए प्रतीक्षा करें, और ध्यान दें कि वहां एक GobbleGobble विधि है, इस तरह कोड को पूरा करें:

String s = "Turkey Baster!";
s.GobbleGobble();

महत्वपूर्ण : जिस वर्ग को विस्तार विधि घोषित की गई है, वह विधि दिखाने के लिए संकलक और अंतर्मुखी प्रोसेसर के लिए उपलब्ध होना चाहिए। यदि आप मैन्युअल रूप से GobbleGobble में टाइप करते हैं, और Ctrl+ .शॉर्टकट का उपयोग करते हैं , तो यह फ़ाइल में निर्देशों का उपयोग करके आपको अधिकार प्राप्त करने में मदद नहीं करेगा।

ध्यान दें कि विधि का पैरामीटर गायब हो गया है। संकलक चुपचाप महत्वपूर्ण बिट्स के चारों ओर घूमेगा, जो हैं:

String s = "Turkey Baster!";
s.GobbleGobble();
^     ^
|     +-- the compiler will find this in the StringExtensions class
|
+-- will be used as the first parameter to the method

इस प्रकार, उपरोक्त कोड कंपाइलर द्वारा इसे में बदल दिया जाएगा:

String s = "Turkey Baster!";
StringExtensions.GobbleGobble(s);

तो कॉल-टाइम पर, इसके बारे में कुछ भी जादुई नहीं है, यह केवल एक स्थिर पद्धति का कॉल है।

ध्यान दें कि यदि आपकी विस्तार विधि एक से अधिक पैरामीटर की घोषणा करती है, तो केवल पहला ही thisसंशोधक का समर्थन करता है , और बाकी को विधि के भाग के रूप में निर्दिष्ट किया जाना चाहिए:

public static void GobbleGobble(this string value, string extra)
{                                            |              |
    ...                                      |              |
}                                            |              |
                                             |              |
+--------------------------------------------+              |
|                                                           |
v                                                           |
s.GobbleGobble("extra goes here");                          |
                        ^                                   |
                        |                                   |
                        +-----------------------------------+

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

इसके अलावा, अपने आप से विस्तार विधियां वास्तव में उपयोगी हैं, इसलिए इस पर पढ़ें।

यहाँ कुछ लिंक दिए गए हैं:


6
मैं निश्चित रूप से "Gobble Gobble Magic" शब्द का उपयोग शुरू करने जा रहा हूं।
क्रिस

Youtube ने फिर से लिंक तोड़ दिया, youtube.com/watch?v=Bz_heb9Rz2g , अभी भी @ 1: 00 और उसके बाद।
लास वी। कार्लसन

इस तरह के कंपाइलर मैजिक्स से भाषा सीखना मुश्किल हो जाता है।
डॉन दिलंगा

8

विस्तार के तरीकों के बाद, मैं उन्हें पागलों की तरह इस्तेमाल कर रहा हूँ .. यहाँ कुछ मैं लगातार उपयोग कर रहा हूँ ..

public static T ChangeType<T>(this object obj)
{
  return (T)Convert.ChangeType(obj, typeof(T));
}

इस तरह काम करता है ।।

int i = "123".ChangeType<int>();
bool valid = "bool".ChangeType<bool>();
int id = dataSet.Tables[0].Rows[0]["Id"].ChangeType<int>();

हाँ, यह हर एक वस्तु पर दिखाई देता है, कष्टप्रद हो सकता है, लेकिन जब से मैं इसे हर डेटा प्रकार के लिए उपयोग करता हूं, यह हर डेटा प्रकार के लिए इसे डुप्लिकेट करने के बजाय इसे किसी ऑब्जेक्ट को संलग्न करने में मदद करता है।

public static string ToXml(this object serializableObject)
{
    var aMemStr = new MemoryStream();
    try
    {
        var serializer = new XmlSerializer(serializableObject.GetType());
        serializer.Serialize(new XmlTextWriter(aMemStr, null), serializableObject);
        return Encoding.UTF8.GetString(aMemStr.ToArray());
    }
    finally { if (aMemStr != null) { aMemStr.Dispose(); } }
}

string xml = dataSet.ToXml();

public static T ToObject<T>(this string xmlString)
{
    var aStream = new MemoryStream(Encoding.UTF8.GetBytes(xmlString));
    try { return (T)new XmlSerializer(typeof(T)).Deserialize(aStream); }
    finally { if (aStream != null) { aStream.Dispose(); aStream = null; } }
}

DataSet dataSet = xml.ToObject<DataSet>();

6

इसका उपयोग विस्तारामेथोड के लिए किया जाता है। मूल रूप से आप htmlHelper ऑब्जेक्ट में हेल्परनाम को 'ग्लू' कर सकते हैं ताकि आप कह सकें:

new HtmlHelper().HelperName(...more regular params);

4

यह एक विस्तार विधि होगी। वे आपको स्थिर विधियों के माध्यम से एक वर्ग को "विस्तारित" करने की अनुमति देते हैं जो मूल वर्ग के बाहर रहते हैं।

उदाहरण के लिए, मान लें कि आपके पास एक सहायक स्ट्रिंग विधि है जिसका उपयोग आप हर समय करते हैं ...

public int CountAllAs(string orig)
{
    return orig.ToLowerInvariant().ToArray().Count(c => c == 'a');
}

और आप इसे कहते हैं ...

string allAs = "aaaA";
int count = CountAllAs(allAs);

ये इतना बुरा नहीं है। लेकिन एक छोटे से बदलाव के साथ, आप इसे एक एक्सटेंशन विधि बना सकते हैं और कॉल थोड़ा प्रीटियर होगा:

public static int CountAllAs(this string orig)
{
    return orig.ToLowerInvariant().ToArray().Count(c => c == 'a');
}

और फिर इसे कॉल करें ...

string allAs = "aaaA";
int count = allAs.CountAllAs();

3

एक्सटेंशन के तरीके ...

... कार्यक्षमता को शामिल करने का एक शानदार तरीका है यदि आप जहां डेकोरेटर पैटर्न का उपयोग कर रहे हैं , लेकिन अपने सभी कोड को फिर से भरने के दर्द के बिना, या एक सामान्य प्रकार के एक अलग नाम का उपयोग कर रहे हैं।

public static class Extensions
{
     public static string RemoveComma(this string value)
     {
         if (value == null) throw new ArgumentNullException("value");
        return value.Replace(",", "");
    }
}  

तो आप इस कोड का उपयोग, कहीं भी आप ऐप में कर सकते हैं।

Console.WriteLine(“Hello, My, Friend”.RemoveComma())

>> Hello My Friend

तो इस कमांड विशेषता का मतलब है कि एक्सटेंशन "जोड़ा" जाएगा, और आपको मान के साथ काम करना चाहिए जैसे कि यह पैरामीटर के रूप में पारित किया गया था।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.