मेरे C # स्रोत में निम्न परिदृश्य हैं:

class A{}

class Dispatch<T>{}

static class DispatchExt
{
    public static void D<T>(this Dispatch<T> d, int a)
    {
         Console.WriteLine("Generic D chosen with a = " + a.ToString());
    }

    public static void D(this Dispatch<A> d, int a)
    {
         Console.WriteLine("D<A> chosen with a = " + a.ToString());
    }
}

class Program
{
     static void D<T>(Dispatch<T> d, int a)
     {
          d.D(a);
     }

     static void Main(string[] args)
     {
         int a = 5;
         var dispatch = new Dispatch<A>();
         dispatch.D(a);
         D(dispatch, a);
     }
}

जब मैं इस कोड को चलाता हूं तो आउटपुट है:

"D<A> को एक = 5" के साथ चुना गया

"जेनेरिक D को एक = 5 के साथ चुना गया"

इस परिणाम ने मुझे आश्चर्यचकित कर दिया, क्योंकि मुझे उम्मीद थी कि दोनों स्थितियों में "D<A> को = 5" के साथ चुना जाएगा।

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

5
Raul Alonso 23 नवम्बर 2015, 22:18

2 जवाब

सबसे बढ़िया उत्तर

विस्तार विधियाँ वाक्यगत शर्करा होती हैं जो केवल स्थैतिक प्रकार प्रणाली से ली गई जानकारी का उपयोग करके संकलन-समय पर व्याख्या की जाती हैं।

अपना पहला उदाहरण लेते हुए, आपके पास यह है:

dispatch.D(a);

dispatch प्रकार Dispatch<A> है, जिसके लिए एक विस्तार विधि मौजूद है। इसलिए संकलक इसे DispatchExt.D(dispatch, a) (गैर-सामान्य संस्करण) में अनुवादित करता है।

आपके दूसरे उदाहरण में, आपके पास यह है:

d.D(a);

d प्रकार Dispatch<T> का है। तो यह जेनेरिक एक्सटेंशन विधि DispatchExt.D<T>(d, a) लेता है।

चूंकि अनुवाद संकलन-समय पर होता है, इसलिए वास्तविक रन-टाइम प्रकार को ध्यान में नहीं रखा जाता है।


यह btw है। अन्य स्थितियों में ओवरलोड का निर्धारण करते समय एक ही व्यवहार का उपयोग किया जाता है: केवल स्थिर संकलन-समय प्रकार को ध्यान में रखा जाता है:

A a = new A();
B b = new B();
A ba = b;

Test(a); // "a"
Test(b); // "b"
Test(ba); // "a"

निम्नलिखित परिभाषाओं का उपयोग करना:

public void Test(A a) { Console.WriteLine("a"); }
public void Test(B a) { Console.WriteLine("b"); }
public class A {}
public class B : A {}
4
poke 23 नवम्बर 2015, 19:41

मुझे लगता है कि आप इस तरह से मतलब रखते हैं - एक अस्तर विधि जो खुद को बुलाती है। मैंने अंकों की संख्या के कई कॉल किए।

using System; 

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            var magic = new Magic();
            var sum = magic.MagicAdd(2).MagicAdd(20).MagicAdd(50).MagicAdd(20).Result;
            Console.WriteLine(sum);
            Console.ReadKey();
        }

    }

    public class Magic
    {
        public int Result { get; set; }

        //method chaining
        public Magic MagicAdd(int num)
        {
            this.Sum(num);
            return this;
        }

        public int Sum(int x)
        {
            this.Result = this.Result + x;
            return this.Result;

        }
    }
}
0
Israel Ocbina 26 जिंदा 2017, 03:21