Fiddle here।सी # 7 मूल्य tuple/deconstruction asymmetry
एक समारोह (string a, string b) F()
देखते हुए, आप टपल यह रिटर्न deconstruct कर सकते हैं:
var (a, b) = F();
(string c, string d) = F();
या आप बस इसे असाइन कर सकते हैं:
var (a, b) e = F();
(string a, string b) f = F();
var g = F(); // One of these things is not like the others.
कक्षा deconstructors पहले मामले की तरह व्यवहार करते हैं। एक वर्ग C
Deconstructor(out string a, out string b)
साथ दिया गया है:
लेकिन संकलक Deconstructor का उपयोग नहीं होगा परोक्ष एक टपल करने के लिए इसे परिवर्तित करने के लिए:
// Cannot implicitly convert type 'C' to '(string a, string b)'
var (a, b) l = c;
जाहिर है आप यंत्रवत् Deconstructor के आधार पर एक अंतर्निहित रूपांतरण लिख सकते हैं :
public static implicit operator (string a, string b) (C c)
{
c.Deconstruct(out string a, out string b);
return (a, b);
}
deconstruction और असाइनमेंट मामलों के बीच वाक्यविन्यास में दृश्य समानता के बावजूद, एक टुपल के संदर्भ पर हस्ताक्षर करना वैरिएबल में कक्षा को डीकोनस्ट्रक्चर करने और फिर उन्हें एक नए टुपल में डालने जैसा नहीं है। हालांकि, आप (int x, int y)
से (double x, double y)
पर निहित रूप से परिवर्तित कर सकते हैं। वैल्यू टुपल्स सिंटैक्टिक-शुगर फीचर की तरह हैं जहां यह ऐसा लगता है जो ऐसा लगता है, और कार्यान्वयन के विवरणों को कभी भी ध्यान में रखें।
यदि मैंने इस बारे में सोचा, तो सी # टीम ने इसके बारे में सोचा, और यदि उन्होंने निहित रूपांतरण के लिए "जादू" समर्थन नहीं जोड़ना चुना, तो उनके पास का एक अच्छा कारण था।
क्या कोई सकारात्मक कारण है कि अंतर्निहित रूपांतरण स्वचालित रूप से एक बुरा विचार क्यों होता?
या क्या यह उन सुविधाओं में से एक है जिन्हें लागत को उचित ठहराने के लिए पर्याप्त मूल्यवान नहीं माना जाता था?
यहाँ that fiddle से कोड है:
public class Program
{
public static void Main()
{
(string a, string b) = F();
(string a, string b) ab = F();
Console.WriteLine($"a: {a} b: {b} ab: {ab}");
var c = new C();
(string d, string e) = c;
// Cannot implicitly convert type 'C' to '(string a, string b)'
(string a, string b) f = c;
Console.WriteLine($"d: {d} e: {e} f: {f}");
// Covariance
(object c, object d) g = F();
// Implicit conversion
(double x, double y) t = G();
}
public static (string a, string b) F()
=> ("A", "B");
public static (int x, int y) G()
=> (0, 1);
}
public class C
{
public String A = "A";
public String B = "B";
public void Deconstruct(out String a, out String b)
{
a = A;
b = B;
}
}
सी # टीम हर कोई अधिक चालाक नहीं हो सकता है, लेकिन मैं पैसे सट्टेबाजी वे कम से कम के रूप में मुझे के रूप में स्मार्ट थे खो कभी नहीं किया है।
जाहिर है, आप निहित निर्णायक नहीं चाहते हैं, वैसे ही आप आमतौर पर कक्षा से दूसरे में अंतर्निहित रूपांतरण नहीं चाहते हैं। इसके अलावा, यह एक ही स्रोत से tuple और deconstructed चर दोनों का उपयोग करने के लिए ज्यादा समझ में नहीं आता है। यह केवल कोड को समझने के लिए कठिन बना देगा। और एक भाषा डिजाइनर के रूप में, वैसे भी सख्त शुरू करने के लिए यह समझ में आता है और फिर अंततः इसके विपरीत से सामान्यीकृत होता है। उदाहरण के लिए, तथ्य यह है कि संदर्भ प्रकार डिफ़ॉल्ट रूप से शून्य हैं, सी # अब सबसे बड़ी डिजाइन गलती के रूप में माना जाता है ... – Phil1970