Fiddle here. bir işlev (string a, string b) F()
Verilen C# 7 değeri tuple/yapışma asimetrisi
var (a, b) = F();
(string c, string d) = F();
Ya da sadece atayabilirsiniz:
var (a, b) e = F();
(string a, string b) f = F();
var g = F(); // One of these things is not like the others.
Sınıf deconstructors ilk vaka gibi davranırlar. Bir sınıf C
Deconstructor(out string a, out string b)
ile Verilen:
Ama derleyici örtülü bir tuplea dönüştürmek için Deconstructor kullanmaz:
// Cannot implicitly convert type 'C' to '(string a, string b)'
var (a, b) l = c;
Açıkçası mekanik Deconstructor dayalı bir örtük dönüştürme yazabilirsiniz : yapısöküm ve atama durumları arasında sözdiziminde görsel benzerlik dikkate alınmaksızın
public static implicit operator (string a, string b) (C c)
{
c.Deconstruct(out string a, out string b);
return (a, b);
}
olarak Bir tuple bir referansın imzalanması, bir sınıfa değişkenlerin deşifre edilmesi ve sonra da yeni bir tuple yerleştirilmesi ile aynı değildir. Ancak, dolaylı olarak (int x, int y)
'u (double x, double y)
'a dönüştürebilirsiniz. Değer tupl'leri, göründüğü gibi yaptıklarını söyleyen sözdizimsi şekerleme özelliğidir ve uygulama ayrıntılarını boşver.
Bunu düşünürsem, C# takımı bunu düşündü ve örtük dönüştürme için "büyü" desteği eklememeyi seçtiyse, iyi bir nedenleri vardı.
Gizli dönüşümün otomatik olarak yapılmasının neden hatalı bir fikir olabileceğinin pozitif bir nedeni var mı?
Ya da maliyeti haklı çıkaracak kadar değerli sayılmayan özelliklerden biri mi?
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;
}
}
C# ekibi herkes daha akıllı olmayabilir, ama onlar en azından benim kadar akıllı olduğunu bahis para kaybetti asla:
İşte that fiddle gelen kod.
Açıkçası, örtülü Yapıçözüm genellikle başka birine bir sınıftan örtük dönüştürme istemiyoruz aynı şekilde istemiyoruz. Ayrıca, aynı kaynaktan gelen hem tuple hem de deconstructed değişkenleri kullanmak çok mantıklı değildir. Bu sadece kodu anlamak zorlaştıracaktı. Ve bir dil tasarımcısı olarak, yine de daha sıkı çalışmaya başlamak ve sonradan aksine tersine genelleştirmek mantıklı. C# şimdi en büyük tasarım yanlışlıkla biri olarak kabul edilir Örneğin, referans tipleri varsayılan olarak null olması edilir ... – Phil1970