Bir kurucuda [Saf] ne zaman kullanılır?


19

.NET'te kod sözleşmeleri hakkında bilgi ediniyorum ve saf yapıcılar fikrini anlamaya çalışıyorum. Kod sözleşmeleri belgelerine durumları:

Bir sözleşme kapsamında çağrılan tüm yöntemler saf olmalıdır; yani önceden var olan herhangi bir durumu güncellememeleri gerekir. Bir saf yöntemin, saf yönteme girdikten sonra oluşturulan nesneleri değiştirmesine izin verilir.

Ve PureAttributebelgeler şöyle diyor:

Bir tür veya yöntemin saf olduğunu, yani herhangi bir görünür durum değişikliği yapmadığını gösterir.

Yöntemler söz konusu olduğunda bu ifadeleri anlıyorum, ama ya yapıcılar? Diyelim ki böyle bir sınıfınız var:

public class Foo
{
    public int Value { get; set; }

    public Foo(int value) {
        this.Value = value;
    }
}

Bu kurucu, yeni Foonesnenin durumunu açıkça etkiler , ancak başka hiçbir yan etkisi yoktur (örn. Parametrelerin hiçbirini manipüle etmez veya saf olmayan yöntemler çağırmaz). Bu aday mı [Pure]değil mi? Bir yapıcıya bir [Pure]öznitelik yerleştirmenin önemi nedir ve bunu kendi kodumda ne zaman yapmalıyım?

Yanıtlar:


14

Bir yöntemi aşağıdakilerle süslersiniz [Pure]:

  • Yöntemin yan etkileri yoksa. Örneğin, yöntem bir veritabanına erişir ve veritabanını değiştirirse veya sonucu veritabanına bağlıysa, saf değildir.

  • Ve kod sözleşmelerinde kullanmayı düşünüyorsanız. Örneğin, yöntem safsa , ancak kod sözleşmelerinde kullanmak gibi bir niyetiniz yoksa, eklemenin [Pure]hiçbir faydası olmaz ve kodunuzu daha hızlı hale getirmez.

Yapıcılar ile ilgili olarak, .NET'te saf oldukları varsayılır ve açık bir özniteliğe ihtiyaç duymazlar. Ben gibi .NET Framework kaynağında birkaç yapıcılar, baktı DateTimeve onlar yok [Pure]niteliğini.

Bunun birkaç nedenden dolayı yapıldığını düşünüyorum:

  • [Pure]Bir sözleşmede sadece sınıfı / yapıyı kullanabilmek için niteliği olmayan parametresiz bir kurucu yazmak zorunda kalamayabilirsiniz.

  • Bazılarının Stringaçık kurucuları yoktur.

  • Yapıcılar, kod sözleşmelerinin dışında bile özel muamele görürler; örneğin, bunların içine istisnalar atmanız beklenmez .

  • [Pure]sadece hayatınızı basitleştirmek için burada bulunan bir konudur, ancak bu özellik ile dekore edilmiş yöntemin saf olduğundan emin olmak için gerçek bir statik kontrol yoktur. void DestroyDatabase()saf olarak dekore edilmiş olabilir ve kod sözleşmeleri yanlış bir şey fark etmez.

    Şu anda Kod Sözleşmelerinin saf olarak beyan edilen yöntemlerin gerçekten saf olup olmadığını kontrol eden bir bileşeni yoktur. Dolayısıyla, bir programcı [Pure] ile bir yöntem dekore ettiyse, sadece inanılır.

    Gönderen Kanunu 5. İhale: Yöntem saflığını

  • .NET Framework'ün kendisi saf olmayan kurucuları içerir. Örneğin , koleksiyonda döngü yapmanın yan etkileri List<T>(IEnumerable<T> collection)varsa aslında saf değildir .

  • Sözleşmeler basit tutulur. Böyle bir sözleşmeyi kolayca hayal edebiliyorum Contract.Requires(!string.IsNullOrEmpty(name)), bu yüzden statik string.IsNullOrEmptysaflığı beyan etmek için iyi nedenler var .

    Öte yandan, StringBuilderdize oluşturmak için bir ihtiyacınız varsa, o zaman bir şey için iş sınıfının bir örnek yöntemini çağırarak kontrol edecek, muhtemelen sözleşmeleri kötüye kullanıyorsunuz. Bu yüzden StringBuilder.ToStringde öyle olsa bile saf olarak işaretlenmiyor (değil mi?)


Sistem türleriyle ilgili birçok kod sözleşmesi, " tam adı" System.Diagnostics.Contracts.Contract "," System.String "," System.IO.Path "veya" System ile başlayan herhangi bir yöntem dahil olmak üzere sözleşme denetleyicisi tarafından üstlenilir. " " Yazın . Ne yazık ki, kod türleri söz konusu olduğunda .NET türlerine bakmanın çok yararlı olup olmadığından emin değilim.
pswg

3
Saflık, kod adı verilen tüm kodların da saf olması veya arayanın "saf" olmaması gereken şeylerden biridir. Tüm kurucuların varsayılan olarak saf kabul edildiğine inanmakta zorlanıyorum.
Frank Hileman

@FrankHileman: ben de. Şu anda bir C # derleyici yok, ama bir yapıcı ve hiçbir [Pure]özniteliği olan bir sınıf yazmak ve kesin bir cevap için bir sözleşmede başka bir yerde kullanmak yeterli olacaktır .
Arseni Mourzenko

1

Nesne, bu durumda oluşturulana kadar kullanılamaz. Bu nedenle yapıcı saftır. Yapıcı başka kod çağırdıysa veya bir temsilci çağırdıysa ve diğer kod mutable özelliğini değiştirdiyse, saf olmazdı. Daha güvenli olmak için, mülkü değişmez hale getirmek daha iyidir.


Saf bir kurucu, saf olmanın diğer koşullarını karşıladığı sürece, mevcut sınıfın durumunu değiştirmesine izin verilen saf bir yöntemdir? BTW, Özellik değiştirilebilir çünkü bu sınıfın kendisi saf olmadığını vurgulamak istedim.
pswg

@pswg: Muhtemelen Microsoft tarafından cevaplanması gereken ilginç bir soru yarattınız. Yapıcı, mutable özelliğini değiştiren bir yöntem çağırdı; inşaatçı hala saf olur mu? Değişikliğin harici izleyiciler için "görünmez" olmasına rağmen teknik olarak olmayacağını düşünüyorum. Orijinal örneğinizde çağrılan başka bir kod olmadığından, aklıma gelen herhangi bir tanımla saf olması gerekir.
Frank Hileman

@pswg: Özellik kümesi de bir yöntem çağrısı dışında .. MSDN forumlarında sormak gerektiğini düşünüyorum.
Frank Hileman

Temel saflık fikrinin, yöntemin gözlemlenebilir herhangi bir değişiklik yapıp yapmadığı olup olmadığını tahmin ediyorum , o zaman bu değişiklikler, herhangi bir arayan tarafından gözlemlenemediği sürece saf olmayan yöntemler olarak adlandırılıp adlandırılmadığına bakılmaksızın , yine de saf bir yöntem olurdu.
pswg

@pswg: Bu soyut tanım. Ama eğer bunlar için bir analizör yazıyor olsaydım, muhtemelen saf olmayan bir yöntem çağrısı da arayanı saf olmayan yapmak için düşünülecektir. Sadece uygulamanın basitliği için. O zaman soru, bir kurucu normal bir yöntem çağrısı veya analizin ne kadar derin gittiğidir.
Frank Hileman
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.