.NET'te ApplicationException nedir?


172

İstisnaları atmak için genellikle yerleşik istisna sınıfları kullanıyorum, örn. ArgumentNullExceptionVe NotSupportedException. Ancak, bazen özel bir istisna kullanmam gerekiyor ve bu durumda yazıyorum:

class SlippedOnABananaException : Exception { }
class ChokedOnAnAppleException : Exception { }

ve bunun gibi. Sonra bunları koduma atıp yakalarım. Ama bugün ApplicationExceptionsınıfa rastladım - bunun yerine mi kullanmalıyım? Bu ne için?

Farklı isimlerle etkili bir şekilde özdeş çok sayıda İstisna sınıfına sahip olmak yetersiz görünüyor (genellikle herhangi bir bireysel işlevselliğe ihtiyacım yok). Ama genel bir yakalama ApplicationExceptionve hatanın ne olduğunu belirlemek için ekstra kod kullanmak zorunda fikrini sevmiyorum .

Koduma nereye ApplicationExceptionuymalı?


35
Harika bir soru, ayrıca akıllıca adlandırılmış örnek istisnalar için +1
Cody Gray

Yanıtlar:


100

Msdn'deki açıklamalara göre :

Ortak dil çalışma zamanı değil, kullanıcı uygulamaları ApplicationException sınıfından türetilen özel özel durumlar atar. ApplicationException sınıfı, uygulamalar tarafından tanımlanan özel durumlar ile sistem tarafından tanımlanan özel durumları birbirinden ayırır.

Kendi istisnalarını oluşturması gereken bir uygulama tasarlıyorsanız, Exception sınıfından özel istisnalar türetmeniz önerilir. Başlangıçta, özel istisnaların ApplicationException sınıfından türemesi gerektiği düşünülüyordu; ancak uygulamada bunun önemli bir değer kattığı görülmemiştir. Daha fazla bilgi için bkz. İstisnalarla İlgili En İyi Uygulamalar.

Onları türet Exception. Ayrıca, garanti edildiği sürece, davalarınız için yeni istisnalar oluşturmada bir sorun görmüyorum. Çerçevede zaten bir istisna olan bir durumla karşılaşırsanız, bunu kullanın;


9
Bu ApplicationExceptionişe yaramaz gibi görünüyor ve sadece geriye dönük uyumluluk nedeniyle var mı?
Beatles1692

Yeni MSDN belgeleri, en az 4.7.2, bu yorumu kaçırmaktadır. Qutoe için teşekkürler: D
Alex

147

Kısa cevap: hiçbir yerde.

Microsoft'un geliştiricilerin tüm özel istisnalarını ApplicationException'dan devralmasını amaçladığı geçmişin bir kalıntısıdır. Kısa bir süre sonra fikrini değiştirdiler ve özel istisnaların temel İstisna sınıfından türetilmesi gerektiğini söylediler. Bkz . MSDN'de İstisnalarla İlgili En İyi Uygulamalar .

Bunun daha geniş çapta dolaşan nedenlerinden biri, Çerçeve Tasarım Yönergeleri'nde Jeffery Richter'in bir çabasından kaynaklanmaktadır :

System.ApplicationException , .NET Framework'ün bir parçası olmaması gereken bir sınıftır. Asıl fikir, SystemException'dan türetilen sınıfların CLR'den (veya sistemden) atılan istisnaları göstermesi, CLR dışı istisnaların ApplicationException'dan türetilmesi idi . Ancak, birçok istisna sınıfı bu modeli takip etmedi. Örneğin, (CLR tarafından atılan) TargetInvocationException ApplicationException öğesinden türetilir . Böylece, ApplicationException sınıfı tüm anlamını yitirdi. Bu temel sınıftan türetilmesinin nedeni, çağrı yığınının üstündeki bazı kodların temel sınıfı yakalamasına izin vermektir. Tüm uygulama istisnalarını yakalamak artık mümkün değildi.

İşte burada. Yönetici özeti, ApplicationException'ın zararlı olmadığı , sadece yararsız olduğu yönündedir .


2
Bunun neden olduğunu bilen var mı ? Uygulama istisnalarını görüntüleyebilmeniz, ancak "programcı berbat" istisnaları görüntülememeniz mantıklı görünmektedir.
Josh Kodroff

9
BTW, bu açıklamadan, bunun kendi başına kötü bir tasarım olmadığı, ancak MSFT'nin uygulamayı bozduğu görülüyor. Bunu başka okuyan var mı?
Josh Kodroff

8
@JoshKodroff: Sorun, eğer uygulama Whizbangtüm istisnalarını bazı ortak hiyerarşi altında yapmak istediğine karar verirse, bu ApplicationExceptionamaç için kullanmanın özel bir WhizbangExceptiontemel sınıf kullanmaya göre gerçekten avantaj sağlayamayacağını düşünüyorum . .Net'in istisna hiyerarşisindeki daha ciddi sorun, ApplicationExceptionistisnaları muhtemelen uygulama-ölümcül, muhtemelen iş parçacığı ölümcül ve yerel sorunla ilgili kategorilere ayırmamak ve bunun yanı sıra anlamlı "bileşik" istisnalar.
supercat

@JoshKodroff: Düzgün tasarlanmış bir istisna çerçevesinde, IMHO, finallybaşka bir istisna beklenirken blok sırasında bir istisna atılırsa , herhangi bir iç içe kural dışı durumla eşleşirse catchçağrı yığınının üstündeki bloklar tetiklenmelidir , ancak diğer istisnalar beklemede kalır. bir bloğu başka bir sokacaklarını aynı mesafede olan blok (herhangi bir uygun olsaydı) blok ve bir çıkış yanındaki dış için zıplayacağını bekleyen herhangi bir istisna dışında blok ya da . catchcatchtryfinallycatchfinally
supercat

2
@JoshKodroff Daha fazla dikkat etmemeye şaşırdığım bir şey daha var. Gerçekten bir "uygulama" nedir? Üçüncü taraf kütüphaneler ne olacak ? Bunlar .Net çerçevesinin bir parçası olmadığından, özgün yönergelere göre ApplicationException öğesinden miras almalıdırlar. Şimdi bu kitaplığı uygulamanızda kullandığınızda ve ayrıca kendi ApplicationExceptions oluşturduğunuzda, artık kendi istisnalarınızı buna dayalı olarak kitaplığın istisnasından ayırt edemezsiniz. Yani işe yaramaz. Bunun yerine, her bileşen, supercat'in açıkladığı gibi, kendi istisna tabanı türlerini tanımlamalıdır.
Oskar Berggren

22

İlk tasarımda, .NET 1.0'da, çerçevenin kendisinin atması SystemExceptionve türetilmesi planlandı ; kullanıcı uygulamaları ise - atılacak ApplicationExceptionve türetilecektir.

Ancak daha sonra .NET 2.0'da bu bırakıldı.

Böylece türetilir Exception.

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.