SORU
5 EKİM 2011, ÇARŞAMBA


Nesneleri birbirine başvuru değişmez?

Bugün sabit nesneler civarında başvuru birbirlerine kendime adapte etmeye çalışıyorum. Muhtemelen tembel değerlendirme kullanmadan bunu yapamazsınız ama bu süreçte (bence) ilginç bir kod yazdım bu sonuca ulaştım.

public class A
{
    public string Name { get; private set; }
    public B B { get; private set; }
    public A()
    {
        B = new B(this);
        Name = "test";
    }
}

public class B
{
    public A A { get; private set; }
    public B(A a)
    {
        //a.Name is null
        A = a;
    }
}

İlginç bulduğum şey veremem bir durumda olduğunu henüz tam olarak oluşturulmuş değil ve Bir iş parçacığı içeren nesne türü gözlemlemek için başka bir yol düşünemiyorum. Neden bu bile geçerli mi? Başka yollar tamamen inşa olmayan bir nesnenin durumunu gözlemlemek için vardır?

CEVAP
5 EKİM 2011, ÇARŞAMBA


Neden bu bile geçerli mi?

Neden geçersiz olmasını bekliyor musunuz?

Bir kurucu içerir kod dışında kod nesnenin durumunu gözlemlemek için önce yürütülen garanti gerekiyordu çünkü.

Doğru. Amaderleyicibu değişmeyen bakımından sorumlu değildir.. Eğer o değişmeyen tatili kod yazarsanız, ve o, bunu yapmak için acıyorşunu yapmayı kes.

Başka yollar tamamen inşa olmayan bir nesnenin durumunu gözlemlemek için vardır?

Emin. Başvuru türleri için, hepsini bir şekilde "kurucu dışında, belli ki, sadece kullanıcı yılından bu yana depolama referansı tutan kod oluşturucu." bu geçirmeden içerir Kurucu sızıntısı olabilir bazı yolları "bu"

  • "Bu" başka bir iş parçacığı statik alan ve bir başvuru
  • yöntem bir arama yapmak ya da yapıcı arayıp pass "bu" bir argüman olarak
  • eğer sanal bir yöntem türemiş sınıf decimal vücut çalışır önce çalıştığı için türetilmiş bir sınıf tarafından geçersiz kılınmış ise sanal ihbar özellikle kötü.

Sadece dedimkullanıcı kodubir başvuru decimal, ama tabii tutarçöp toplayıcıayrıca bir başvuru içerir. Bu nedenle, ilginç bir şekilde bir nesne olabilir gözlenen bir yarı-devlet inşa ise nesnenin sahip bir yıkıcı ve yapıcı bir istisna atar (ya da alır zaman uyumsuz bir istisna gibi bir iş parçacığı iptal; daha sonra.) Bu durumda, nesne ölü olmak üzere olduğunu ve bu nedenle kesinleşmiş olması gerekir, ama sonlandırıcı iş parçacığı nesnenin yarı başlatıldı durumunu görebilirsiniz. Ve şimdi yarı inşa nesneyi görebilen geri kullanıcı kodu.

Yıkıcılar bu senaryo karşısında güçlü olmak gerekir.Yıkıcı bir nesne yok olma hiç bir zaman tam olarak inşa edilmiş olabilir, çünkü herhangi bir nesnenin değişmeyen kurucu bakımlı olmak kurmak bağımlı olmamalıdır.

Yarım inşa nesne dışında kod tarafından gözlenen olabilecek başka bir deliliğin eğer yıkıcı senaryoda yarım başlatıldı nesnenin üzerinde, ve sonra görürse tabiikopya bir referansbu statik bir alana nesne, böylece yarı-yapılandırılmış, yarı-kesinleşmiş nesne sağlanması ölümden kurtardı.Lütfen bunu yapma.Eğer acırsa, dediğim gibi, bunu yapma.

Eğer bir değer türü kurucusu ve eğer o şeyler temelde aynı, fakat mekanizması içinde bazı küçük farklılıklar vardır. Dil gerektiren bir kurucu çağrısı üzerine bir değer yazın oluşturur geçici bir değişken tek decimal girebiliyor, mutasyona değişken ve bir yapı kopyasının mutasyona uğramış değer gerçek depolama. Eğer yapıcı atar, sonra nihai depolama yarı mutasyona uğramış bir durumda olmasını sağlar.

Yapı beri kopya atom olması garanti değildir, bunu unutmayıneğer bu durumda iseniz, başka bir iş parçacığı yarı mutasyona uğramış bir durumda depolama; kilitleri doğru olarak kullanmak mümkün. Ayrıca, iş parçacığı iptal gibi bir zaman uyumsuz özel durum yapı bir kopyasını yarısına atılmış olması mümkündür. Olmayan katına çıkar bu sorunlar ne olursa olsun kopyala-doktora ya da geçici bir "" kopyala. normal olup olmadığını ortaya çıkışı Ve genel olarak, çok az değişmezler eğer asenkron istisnalar varsa korunur.

Pratikte, C# derleyicisi eğer bu senaryo ortaya çıkabilmesi için yolu yok bunu belirlemek geçici tahsisi ve kopya çekip optimize eder. Eğer yeni değer bir yineleyici bloğu lambda tarafından ve kapalı olmayan bir yerel başlatılıyor ise, örneğin, daha sonra S s = new S(123); doğrudan s programlanıyor.

Yazın kurucular nasıl çalıştığı hakkında daha fazla bilgi için bkz:

Debunking another myth about value types

Ve hakkında daha fazla bilgi için C# dili semantiği seni kendinden kurtarmak için, bakın deneyin:

Why Do Initializers Run In The Opposite Order As Constructors? Part One

Why Do Initializers Run In The Opposite Order As Constructors? Part Two

Ele aldığımız konu sapmış gibi görünüyor. Bir yapı olabilir tabii gözlemlemek bir nesne, yarı inşa aynı yolu -- kopya yarısında inşa edilmiş nesne için bir statik alan, arama yöntemi ile "bu" argüman olarak, ve benzeri. (Belli ki daha türetilmiş bir tür sanal bir yöntemi çağırmak yapılar ile ilgili bir sorun değildir.) Ve dediğim gibi, son depolama için geçici bir kopya değil atom olduğunu ve bu nedenle başka bir iş parçacığı yarım kopyalanan yapı gözlemleyebilirsiniz.


Nasıl birbirine başvuru değişmez nesneler yapmak mı? işte sana bir soru kök nedeni ele alalım:

Keşfettiğin gibi normalde yok. Eğer iki sabit nesneler bu referans birbirimizi o zaman mantıklı bir oluştururlaryönlendirilmiş grafik siklik. Sadece değişmez yönlendirilmiş bir grafik bina düşünebilirsiniz! Bunu yapmak oldukça kolay. Değişmez yönlendirilmiş bir grafik oluşur:

  • Her bir değeri içeren düğüm sabit, değişmez bir liste.
  • Her grafik bir kenar başlangıç ve bitiş noktası vardır değişmez düğüm çiftleri, değişmez bir liste.

Şimdi düğümleri sizin yaptığınız gibi A ve B "referans" birbirimizi:

A = new Node("A");
B = new Node("B");
G = Graph.Empty.AddNode(A).AddNode(B).AddEdge(A, B).AddEdge(B, A);

Ve bitti, bir grafik var A ve B "referans" birbirimizi.

Sorun, tabii ki, elinde olmadan G B için Bir elde edemezler. Başvururken ekstra bir bilgiye sahip olması kabul edilemez olabilir.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • calicoJake

    calicoJake

    29 EKİM 2007
  • merumputdotcom

    merumputdotc

    24 ŞUBAT 2012
  • PaulGBelliveau

    PaulGBellive

    5 Mart 2009