C # / .net'te atılan istisnalar nasıl belgelenir


139

Şu anda şirket içindeki diğer geliştiriciler tarafından dahili olarak kullanılacak küçük bir çerçeve yazıyorum.

İyi Intellisense bilgileri sağlamak istiyorum, ancak atılan istisnaları nasıl belgeleyeceğimden emin değilim .

Aşağıdaki örnekte:

public void MyMethod1()
{
    MyMethod2();

    // also may throw InvalidOperationException
}

public void MyMethod2()
{
    System.IO.File.Open(somepath...); // this may throw FileNotFoundException

    // also may throw DivideByZeroException
}

İstisnaları belgelemek için biçimlendirme olduğunu biliyorum:

/// <exception cref="SomeException">when things go wrong.</exception>

Ne anlamıyorum tarafından çağrılan kod tarafından atılan istisnalar nasıl belgelenir MyMethod1()?

  • Tarafından atılan istisnaları belgelemeli miyim MyMethod2()
  • Tarafından atılan istisnaları belgelemeli miyim File.Open()?

Olası istisnaları belgelemenin en iyi yolu ne olabilir?


4
Bunun tam olarak sorduğunuz şey olmadığını biliyorum (ve bu gerçekten eski bir soru), ancak Eric Lippert (microsoft C # derleyicisi ve tasarım ekiplerindeki ana geliştirici), her geliştiricinin düşündüğüm 4 istisna türü hakkında bir blog yazısı yazdı kural dışı durum işleme kodu yazarken düşünmek gerekir: blogs.msdn.com/b/ericlippert/archive/2008/09/10/…
javajavajavajavajava

@javajavajavajavajava Bağlantı için teşekkürler - kesinlikle okumaya değer.
Arnold Zokas

Bu geçerli bir soru olduğunu düşünüyorum çünkü C # istisnaları düzgün bir şekilde belgelemek hiç belli değil ve 50K görünümleri de çok millet için de açık olmadığını gösterir. En çok oylanan ikinci cevap, bunu belgelemek için mevcut xmldoc'ları kullandığını gösterdiği için çok yararlıdır. Yeniden açmak için oylama. Bu "görüşe dayalı" yakın neden, aslında çok yararlı programlama sorularının çoğunu öldürmektir.
Alexei

Yanıtlar:


110

Kodunuz tarafından atılabilecek her istisnayı, arayabileceğiniz herhangi bir yöntem de dahil olmak üzere belgelemeniz gerekir.

Liste biraz büyürse, kendi istisna türünüzü oluşturmak isteyebilirsiniz. Metodunuzda karşılaşabileceğiniz her şeyi yakalayın, bunları istisnanıza sarın ve atın.

Bunu bu şekilde yapmak isteyebileceğiniz başka bir yer, yönteminiz API'nizin yüzündeyse. Tıpkı bir cephenin çoklu arayüzleri tek bir arayüzde basitleştirmesi gibi, API'niz de çoklu istisnaları tek bir istisnada basitleştirmelidir. Kodunuzu arayanlar için kullanımını kolaylaştırır.


Andrew'un bazı endişelerini yanıtlamak için (yorumlardan), üç tür istisna vardır: Bilmediğiniz, bildiğiniz ve hakkında bir şey yapamayanlar ve bildiğiniz ve hakkında bir şeyler yapabilecek olanlar.

Senin hakkında bilmediklerini bırakmak istiyorlar. Bu hızlı başarısız ilkesi - verilerinizi bozan bir durum girmek daha app çökmesine daha iyi. Çökme size neler olduğunu ve nedenini anlatacak, bu da bu istisnayı "bilmedikleriniz" listesinden çıkarmanıza yardımcı olabilir.

Bildiğiniz ve yapamayacağınız şeyler OutOfMemoryExceptions gibi istisnalardır. Aşırı durumlarda, bunun gibi istisnaları ele almak isteyebilirsiniz, ancak oldukça dikkat çekici gereksinimleriniz yoksa, onlara ilk kategori gibi davranırsınız - hadi gidelim. Eğer Do sahip bu istisnaları belgelemek için? Bir nesneyi yeni oluşturan her yöntemde OOM'ları belgelemek oldukça aptalca görünecektir.

Bildiğiniz ve hakkında bir şeyler yapabileceğiniz, belgelendirmeniz ve paketlemeniz gerekenlerdir.

İstisna işlemeyle ilgili daha fazla yönergeyi burada bulabilirsiniz.


3
İtiraf etmeliyim ki bu pek pratik gelmiyor. Ben kaç potansiyel istisnalar diyebilirim herhangi bir kod tarafından atılabilir düşünemiyorum, artı orada yakalamak ve sarmak istemeyeceğiniz OutOfMemoryException gibi şeyler var.
Andrew Hare

3
Cevabınız iyi mi olacak, ama aslında birbiriyle çelişen iki cevap. "kodunuz tarafından atılabilecek her istisnayı belgeleyin" ve "Bildiğiniz ve hakkında bir şeyler yapabilecekleriniz belgelendirmeniz gerekenlerdir".
Timtam

2
@Tymek: Hayır. İlk yarı, "istisnaları nasıl belgelemeliyim" sorusunu yanıtladı, ikinci kısım "hangi istisnaları belgelemeliyim" konusuna açıkça açık bir cevap verdi. Birincisi, meydana gelebilecek her istisnayı belgelediğiniz anlamına gelmez. Bazı insanlar çok gerçek, ikinci yarıyı gerektiriyorlar.

5
@Tymek Bence bu konuda bir şeyler yapabiliyorsanız, neden yeniden düşünüp belgelemek yerine bu konuda bir şey yapmıyorsunuz? " Müşteri kodunun bir şey yapabileceğini bildiğiniz" ifadesi daha doğru olabilir. Bu çelişkiyi ortadan kaldırır, çünkü bunlar belgelemek için ideal istisnalardır.
mo.

'Bırakın' istisnalarına gelince, onları her zaman onları kaydeden daha düşük bir seviyede yakalayabilirsiniz. Bilirsin; sadece program çökmesine izin kullanıcı dostu bir yol yapmak.
Nyerguds

96

Standart xml belgelerini kullanmalısınız .

/// <exception cref="InvalidOperationException">Why it's thrown.</exception>
/// <exception cref="FileNotFoundException">Why it's thrown.</exception>
/// <exception cref="DivideByZeroException">Why it's thrown.</exception>
public void MyMethod1()
{
    MyMethod2();
    // ... other stuff here
}

/// <exception cref="FileNotFoundException">Why it's thrown.</exception>
/// <exception cref="DivideByZeroException">Why it's thrown.</exception>
public void MyMethod2()
{
    System.IO.File.Open(somepath...);
}

/// <exception cref="FileNotFoundException">Why it's thrown.</exception>
public void MyMethod3()
{
    try
    {
        MyMethod2();
    }
    catch (DivideByZeroException ex)
    {
        Trace.Warning("We tried to divide by zero, but we can continue.");
    }
}

Bu şekilde yapmanın değeri, oluşabilecek bilinen istisnaların belgelerini sağlamanızdır. Görsel dokümantasyon kullanıyorsanız ve size (veya diğerlerini) daha sonra bekleyebileceğiniz istisnaları hatırlatabiliyorsa, bu dokümantasyon bilgi bölümünde mevcuttur.

Belirli istisna türlerini belirtmek istersiniz, çünkü diğer türler ciddi bir sorunun sonucudur ve düzeltilemez.


1
Bu nasıl bir değer katıyor? Örneğin, tüm bu istisnalar İstisna tipinin türevleridir. Deneyimlerime göre, yöntemlerinizde çağrılan diğer API'lerden atılabilecek diğer tüm istisna türlerini düşünmek pratik olmayacaktır. Demek istediğim, herhangi bir İşletme bilgisi taşıyanlardan bir yöntemden atılan herhangi bir istisna hakkında endişelenmemeliyiz.
Illuminati

7
@ShiranGinige deneyiminiz yanlış.
Grozz

35

Birkaç harika eklenti kullanarak dokümantasyon sürecinizi kolaylaştırabilirsiniz. Bunlardan biri, XML-doc yorumları üreten Visual Studio için ücretsiz bir eklenti olan GhostDoc . Ayrıca, ReSharper kullanıyorsanız , atılan istisnalar için XML yorumları oluşturmak için bir seçenek ekleyen ReSharper için mükemmel Ajan Johnson Eklentisine bir göz atın .

Güncelleme: Görünüşe göre Agen Johnson, R # 8 için mevcut değil, alternatif olarak ReSharper için olağanüstü ödeme ...

Adım 1: GhostDoc XML yorumunu (Ctrl-Shift-D) oluşturur, ReSharper için Agent Johnson eklentisi de istisnayı belgelemeyi önerir:

Aşama 1

2. Adım: İstisna belgelerini eklemek için ReSharper'ın kısayol tuşunu (Alt-Enter) kullanın:

adım 2 http://i41.tinypic.com/osdhm

Umarım yardımcı olur :)


Tinipik bağlantılar kopmuştur.
ANeves

11

Anladığım kadarıyla, <exception> öğesini kullanmanın amacı, istisnalar değil, dekorasyon yöntemlerinde kullanmaktır:

/// <summary>Does something!</summary>
/// <exception cref="DidNothingException">Thrown if nothing is actually done.</exception>
public void DoSomething()
{
// There be logic here
}

Çağrılan diğer yöntemlerle atılabilecek istisnalar, bu yöntemlerde yakalanmalı, ele alınmalı ve belgelenmelidir. .NET tarafından atılabilecek özel durumlar veya açıkça kendi kodunuz tarafından atılan özel durumlar belgelenmelidir.

Bundan daha spesifik hale geldikçe, belki kendi özel istisnalarınızı yakalayıp atabilirsiniz?


4

Yöntemin sözleşmesinin bir kısmı, ön koşulların geçerli olup olmadığını kontrol etmek olmalıdır, bu nedenle:

public void MyMethod2()
{
    System.IO.File.Open(somepath...); // this may throw FileNotFoundException
}

olur

/// <exception cref="FileNotFoundException">Thrown when somepath isn't a real file.</exception>
public void MyMethod2()
{
    FileInfo fi = new FileInfo( somepath );
    if( !fi.Exists )
    {
        throw new FileNotFoundException("somepath doesn't exists")
    }
    // Maybe go on to check you have permissions to read from it.

    System.IO.File.Open(somepath...); // this may still throw FileNotFoundException though
}

Bu yaklaşımla, atılmış OutOfMemoryException olabileceğini belgelemek zorunda kalmadan açıkça attığınız tüm istisnaları belgelemek daha kolaydır .


1
Eğer Openaramanın yine de atması istisnasını çoğaltacaksanız, bu kontrolün amacının ne olduğundan emin değilsiniz (not ettiğiniz gibi, bir yarış olduğunu ve kontrolün başarıyı garanti etmediğini belirtmiyorum Open). .
Mat Enright

1
@MattEnright Verdi, ama ben bunu göstermek için biraz yaptım ...
Rowland Shaw

1

Yönteminiz tarafından atılabilecek tüm istisnaları belgelemeniz gerekir.

Uygulama ayrıntılarını gizlemek için MyMethod2'den bazı istisnaları kendim ele almaya çalışacağım.

İstisna ile başa çıkamaz veya çözemezseniz, onları geri almayı düşünebilirsiniz. Çoğunlukla arayan için daha anlamlı bir istisna halinde paketlenir / paketlenir.


1

Aslında, daha önce yanıtlandığı gibi, istisnaları belgelemenin yolu XML Yorumları kullanmaktır.

Eklentilere ek olarak, istisnaların belgelendiğinden emin olmak için TFS ile entegre edilebilen statik analiz araçlarını da kullanabilirsiniz.

Aşağıdaki bağlantılarda, StyleCop için yöntemlerinizin oluşturduğu özel durumları doğrulamak üzere nasıl özel bir kural oluşturulacağını görebilirsiniz.

http://www.josefcobonnin.com/post/2009/01/11/Xml-Documentation-Comments-Exceptions-I.aspx http://www.josefcobonnin.com/post/2009/01/15/Xml-Documentation -Yorumlar-İstisnalar-II.aspx

Saygılarımızla.


0

Yöntemin beklenen istisnalar Belgenizde, örneğinizde kullanıcıya bu yöntemin istisna bulunmayan bir dosyayı atabileceğini bildiririm.

Unutmayın, arayanla ne bekleyeceğini bildirmek, böylece onunla nasıl başa çıkılacağını seçebilirler.

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.