Soru Birden fazla istisnai bir kerede mi ele geçirdiniz?


Sadece yakalamak için cesareti yok System.Exception. Bunun yerine, sadece "bilinen" istisnalar yakalanmalıdır.

Şimdi, bu bazen gereksiz tekrarlayan kodlara yol açar, örneğin:

try
{
    WebId = new Guid(queryString["web"]);
}
catch (FormatException)
{
    WebId = Guid.Empty;
}
catch (OverflowException)
{
    WebId = Guid.Empty;
}

Merak ediyorum: Her iki istisnayı da yakalamanın ve sadece WebId = Guid.Empty Bir kez ara

Verilen örnek oldukça basittir, çünkü sadece GUID. Ancak, bir nesneyi birçok kez değiştirdiğiniz yerde bir kod hayal edin ve eğer manipülasyonlardan biri beklenen bir şekilde başarısız olursa, "sıfırlamak" istersiniz. object. Ancak, beklenmedik bir istisna varsa, yine de daha yüksek atmak istiyorum.


1712
2017-09-25 20:56


Menşei


Eğer .net 4 ve üzeri kullanıyorsanız agregateexception kullanmayı tercih ederim msdn.microsoft.com/en-us/library/system.aggregateexception.aspx - Bepenfriends
Bepenfriends-Beriden System.Guid atmıyor AggregateExceptionEğer (veya birisi) bir AggregateException vb. içine nasıl sarılacağını gösteren bir cevap gönderebilirseniz, bu harika olurdu. - weir
Kullanarak AggregateException: Kendi koduma bir AggregateException atma - DavidRR
"System.Exception'ı yakalamak kesinlikle tavsiye edilmez." -ve yöntem 32 tür istisna atarsa, ne yapar? Her biri için ayrı ayrı yazma yetkisi var mı? - giorgi.m
Sahip olduğun gibi devam et. Eğer bir catch cümlesi başına sadece bir satır istiyorsanız, kodu bir hata işleyicisine taşıyın. - rolls


Cevaplar:


Yakalamak System.Exception ve türleri aç

catch (Exception ex)            
{                
    if (ex is FormatException || ex is OverflowException)
    {
        WebId = Guid.Empty;
        return;
    }

    throw;
}

1792
2017-09-25 21:01



Ne yazık ki, FxCop (yani Visual Studio Kod Analizi), İstisnayı yakaladığınızda bunu sevmez. - Andrew Garrison
İstisna yakalama konusunda katılıyorum, ancak, bu durumda, catch bir filtredir. Diğer istisna türlerini ele alacak bir katman daha yüksek olabilir. Bir catch (Exception x) içermesine rağmen, bunun doğru olduğunu söyleyebilirim. Program akışını değiştirmez, sadece bazı istisnaları işler ve uygulamanın diğer geri kalanlarına da izin verir. - lkg
FxCop'un en son sürümü, yukarıdaki kod kullanıldığında bir istisna alamaz. - Peter
OP'in kodunda neyin yanlış olduğundan emin değil. # 1 kabul edilen cevap neredeyse iki kat daha fazla ve çok daha az okunabilir. - João Bragança
@ JoãoBragança: Bu örnekte bu cevap daha fazla satır kullansa da, örneğin IO dosyası ile uğraştığınızı hayal etmeyi deneyin. Tek yapmanız gereken, bu istisnaları yakalamak ve bazı günlük mesajlaşma yapmaktır, ancak yalnızca sizin IO yöntemleri. Sonra genellikle daha büyük bir sayı (yaklaşık 5 veya daha fazla) farklı istisnalar ile uğraşmak zorundasınız. Bu durumda, bu yaklaşım size bazı çizgiler kazandırabilir. - Xilconic


DÜZENLE: C # 6.0'dan itibaren istisna filtrelerinin şu anda gitmek için mükemmel bir yol olduğunu söyleyen diğer kişilerle aynı fikirdeyim: catch (Exception ex) when (ex is ... || ex is ... )

Yine de, tek-uzun-planlı yerleşimden nefret ediyorum ve kişisel olarak kodu aşağıdaki gibi ortaya koyardım. Bunun estetik olduğu kadar işlevsel olduğunu düşünüyorum, çünkü bunun anlaşılmayı geliştirdiğine inanıyorum. Bazıları aynı fikirde olmayabilir:

catch (Exception ex) when (
    ex is ...
    || ex is ...
    || ex is ...
)

ORİJİNAL:

Buradaki partiye biraz geç kaldığımı biliyorum, ama kutsal duman ...

Doğrudan kovalamaca kesmek, bu tür bir yanıt daha önceki bir cevabı yineler, ancak gerçekten birkaç istisna türü için ortak bir eylem gerçekleştirmek istiyorsanız ve tek bir yöntemin kapsamı dahilinde her şeyi düzenli ve düzenli tutmak istiyorsanız, neden sadece bir lambda kullanmayın / kapatma / satır içi işlevi aşağıdaki gibi bir şey yapmak için? Demek istediğim, şanslar oldukça iyi olacak ki, bu kapatmayı sadece her yerde kullanabileceğiniz ayrı bir yöntem yapmak istediğinizi fark edeceksiniz. Ancak, kodun geri kalanını yapısal olarak değiştirmeden bunu yapmak çok kolay olacaktır. Sağ?

private void TestMethod ()
{
    Action<Exception> errorHandler = ( ex ) => {
        // write to a log, whatever...
    };

    try
    {
        // try some stuff
    }
    catch ( FormatException  ex ) { errorHandler ( ex ); }
    catch ( OverflowException ex ) { errorHandler ( ex ); }
    catch ( ArgumentNullException ex ) { errorHandler ( ex ); }
}

Yardım edemem ama merak ediyorumuyarı: Önceden biraz ironi / sarcasm) neden dünyadaki tüm bu çabaları temelde sadece aşağıdakileri değiştirmek için gidiyor:

try
{
    // try some stuff
}
catch( FormatException ex ){}
catch( OverflowException ex ){}
catch( ArgumentNullException ex ){}

... sonraki kod kokusunun bazı çılgın değişimleriyle, örnek vermek gerekirse, sadece birkaç tuşa basmış olduğunuzu iddia etmek için.

// sorta sucks, let's be honest...
try
{
    // try some stuff
}
catch( Exception ex )
{
    if (ex is FormatException ||
        ex is OverflowException ||
        ex is ArgumentNullException)
    {
        // write to a log, whatever...
        return;
    }
    throw;
}

Çünkü kesinlikle otomatik olarak okunabilir değil.

Verilen, üç aynı örnekleri /* write to a log, whatever... */ return; ilk örnekte.

Ama bu benim amacım. Fonksiyonları / yöntemleri duydun mu? Ciddi anlamda. Ortak yaz ErrorHandler işlev ve her catch bloğundan onu çağırır.

Bana sorarsanız, ikinci örnek ( if ve is Anahtar kelimeler), projenizin bakım aşamasında önemli ölçüde daha az okunabilir ve aynı anda önemli ölçüde daha fazla hataya açık.

Programlamada göreceli olarak yeni olabilecek herkes için bakım aşaması, projenizin genel ömrünün% 98.7'sini veya daha fazlasını içerecek ve bakım işini yapan zavallı mülteci neredeyse kesinlikle senden başkası olacak. Ve zamanlarının% 50'sini isminizi lanetleyen işe harcayacakları çok iyi bir şans var.

Ve tabii ki FxCop size ateş ediyor ve siz de AyrıcaKodunuzda, çalışan programla tam olarak ilgisi olan bir öznitelik ekleyin ve yalnızca FxCop'a, vakaların% 99,9'unda işaretlemede tamamen doğru olan bir sorunu görmezden gelmesini söylemek için var. Ve üzgünüm, yanılmış olabilirim, ama aslında "göz ardı et" özniteliği, aslında uygulamanıza derlenmiş değil mi?

Bütün koyarak if Tek satırda test yapmak daha kolay okunabilir mi? Sanmıyorum. Demek istediğim, uzun zaman önce bir satırda daha fazla kod koymanın "daha hızlı koşmasını" sağlayacağını iddia eden başka bir programcı var. Ama tabi ki acımasızca çılgın kuruydu. Ona açıklamaya çalışarak (düz bir yüzle - ki bu zorlayıcıydı) tercüman ya da derleyicinin bu uzun çizgiyi ayrı ayrı tek-komut-satır içi ifadelere nasıl ayıracağı - esasen sonuca denk olsaydı sonuçla aynıydı. Sadece derleyiciyi dışarıdan zahmetli bir şekilde çözmeye çalışmak yerine kodun okunabilir olmasını sağladı - herhangi bir etkisi olmadı. Ama ben digress.

Ne kadar az Bu, üç farklı özel durum türü eklediğinizde, şu andan bir iki ay sonra okunabilir mi? (Cevap: alır bir çok daha az okunabilir).

Asıl önemli noktalardan biri, her gün baktığımız metinsel kaynak kodunun biçimlendirilmesinin en önemli noktasını, kodun çalışması sırasında gerçekten gerçekleşen diğer insanlara gerçekten, gerçekten açık olması. Derleyici kaynak kodunu tamamen farklı bir şeye dönüştürdüğünden ve kod biçimlendirme stiliniz hakkında daha az ilgilenemediğinden. Yani all-on-one-line da tamamen berbat.

Sadece söylüyorum...

// super sucks...
catch( Exception ex )
{
    if ( ex is FormatException || ex is OverflowException || ex is ArgumentNullException )
    {
        // write to a log, whatever...
        return;
    }
    throw;
}

370
2017-10-12 00:24



Bu soruya ilk kez rastladığımda, hep kabul edilen cevabın üstündeydim. Cool Sadece hepsini yakalayabilirim Exceptions ve türü kontrol edin. Kodu temizlediğini sanıyordum, ama bir şey bana soruya geri dönmemi sağladı ve aslında soruya verilen diğer cevapları okudum. Bir süreliğine çiğnedim ama seninle aynı fikirdeyim. Bu Daha kodunuzu kurutmak için bir işlevi kullanmak için okunabilir ve korunabilir, her şeyi yakalamak, bir listeyle karşılaştırmak, kodları kodlamak ve atmak için türü kontrol edin. Geç geldiğiniz için ve alternatif ve sane (IMO) seçeneği sağladığınız için teşekkür ederiz. +1. - erroric
Eklemek istediğinizde bir hata işleme işlevi kullanılmazdı. throw;. Her catch bloğundaki bu kod satırını tekrarlamanız gerekir (açıkçası dünyanın sonu değil, tekrarlanması gerekecek kod olduğundan bahsetmeye değer). - kad81
@ kad81, bu doğru, ama yine de tek bir yerde günlüğe kaydetme ve temizleme kodu yazma ve ihtiyacınız olduğunda tek bir yerde değiştirerek, temel istisnası türünü yakalama olmadan daha sonra dallanma dayalı istisna türü. Ve bu bir ekstra throw(); Her catch bloğundaki ifade, IMO'nun ödenmesi gereken küçük bir bedeldir ve yine de gerekirse özel istisna tipine özgü temizlik yapmak için sizi pozisyonda bırakır. - Craig
Hi @Reitffunk, sadece kullan Func<Exception, MyEnumType> yerine Action<Exception>. budur Func<T, Result>, ile Result dönüş tipi olmak. - Craig
Burada tam bir anlaşma yapıyorum. Ben de ilk cevabı okudum ve mantıklı görünüyor. Tüm özel durum işleyicileri için genel 1'e taşındı. İçimdeki bir şey içten içe kusmumu yarattı ... ben de kodu geri aldım. Sonra bu güzelliğe rastladım! Bu ihtiyaçlar kabul edilen cevap olmak - Conor Gallagher


Başkalarının işaret ettiği gibi, if Neler olup bittiğini belirlemek için catch bloğunuzun içinde. C # 6 Özel Durum Filtrelerini destekler, böylece aşağıdakiler çalışır:

try { … }
catch (Exception e) when (MyFilter(e))
{
    …
}

MyFilter yöntem daha sonra böyle bir şeye benzeyebilir:

private bool MyFilter(Exception e)
{
  return e is ArgumentNullException || e is FormatException;
}

Alternatif olarak, bu hepsi satır içi yapılabilir (ne zaman ifadesinin sağ tarafı sadece bir boole ifadesi olmak zorundadır).

try { … }
catch (Exception e) when (e is ArgumentNullException || e is FormatException)
{
    …
}

Bu bir if içinde ifade catch istisna filtrelerini kullanarak engelleme olmayacak yığını gevşeyin.

İndirebilirsin Visual Studio 2015 Bunu kontrol etmek için.

Visual Studio 2013'ü kullanmaya devam etmek istiyorsanız, aşağıdaki nuget paketini yükleyebilirsiniz:

Yükleme Paketi Microsoft.Net.Compilers

Yazma zamanında bu C # 6 için destek içerir.

Bu pakete başvurmak, projenin   içerdiği C # ve Visual Basic derleyicilerinin belirli bir sürümü   herhangi bir sistem yüklü sürümü aksine, paket.


241
2018-04-04 13:59



Sabırsız bir şekilde 6 resmi yayın bekliyor ... Bu ne zaman olur bu çekini görmek istiyorum. - RubberDuck
@RubberDuck C # 6 null yayılma operatörü için ölüyorum. Kararsız bir dil / derleyici riskine değdiğini ekibimin geri kalanına ikna etmeye çalışıyorum. Büyük etkisi ile çok küçük iyileştirmeler. Cevap olarak işaretlenmeye gelince, önemli değil, insanlar bunu gerçekleştirecek / mümkün olduğu sürece mutlu olurum. - Joe
Sağ?! Yakın gelecekte kod tabanına iyi bakacağım. =) Çekin önemli olmadığını biliyorum, ama kabul edilen cevap yakında modası geçmiş olsun diye, OP'nin bunun uygun bir görünürlük sağlamak için bunu kontrol etmesini bekliyorum. - RubberDuck
Bu kısmen bu yüzden henüz @Joe vermedim. Bunun görünür olmasını istiyorum. Yine de, netlik için bir satır içi filtre örneği eklemek isteyebilirsiniz. - RubberDuck


Ne yazık ki, ne yazık ki, bunu yapmak için bir istisna filtresi gerekiyor ve C # MSIL'in bu özelliğini göstermiyor. VB.NET, bu yeteneğe sahip olsa da, ör.

Catch ex As Exception When TypeOf ex Is FormatException OrElse TypeOf ex Is OverflowException

Yapabilecekleriniz, hata kodunuzu kapsüllemek için anonim bir işlev kullanmak ve ardından bu özel yakalama bloklarında aramaktır:

Action onError = () => WebId = Guid.Empty;
try
{
    // something
}
catch (FormatException)
{
    onError();
}
catch (OverflowException)
{
    onError();
}

184
2017-09-25 21:03



İlginç bir fikir ve VB.net'in C # 'ye göre bazı ilginç avantajları olduğu başka bir örnek - Michael Stum♦
@MichaelStum ile birlikte o tür bir sözdizimi Çok nadiren buna çağıracağım. titreme - MarioDS
İstisna filtreleri c # 6 geliyor! Filtrelerin kullanımının geri dönüşüm lehine farkını not edin roslyn.codeplex.com/discussions/541301 - Arne Deruwe
@ArneDeruwe Bu bağlantı için teşekkür ederiz! Yeniden atmamak için daha önemli bir sebep öğrendim: throw e; stacktrace yok eder ve çağrı yığını, throw; "sadece" calltack'ı imha eder (çökme-kazmayı işe yaramaz hale getirir!) A çok Kaçınılması mümkün değilse, kullanmak için iyi bir sebep! - AnorZaken
Eğer hata yapmazsam, VB'deki bir yakalamayı da yapabilirsiniz. Try Catch ex As ArgumentException Catch ex As NullReferenceException End Try Ama ne yazık ki C # öyle bir yardımcı yöntemle kalmıyor ya da jenerik olarak yakalanıyor ve türü belirliyoruz. - David Carrigan


Bütünlük adına, beri .NET 4.0Kod şu şekilde yeniden yazılabilir:

Guid.TryParse(queryString["web"], out WebId);

TryParse biçem yanlış değilse asla istisnalar atar ve yanlış döndürür, WebId'yi Guid.Empty.


Dan beri C # 7 Bir değişkeni ayrı bir satırda tanıtmaktan kaçınabilirsiniz:

Guid.TryParse(queryString["web"], out Guid webId);

Ayrıca, henüz sürüm 4.6’dan itibaren .NET Framework’de bulunmayan geri dönen tupleri ayrıştırmak için yöntemler de oluşturabilirsiniz:

(bool success, Guid result) TryParseGuid(string input) =>
    (Guid.TryParse(input, out Guid result), result);

Ve bunları şöyle kullanın:

WebId = TryParseGuid(queryString["web"]).result;
// or
var tuple = TryParseGuid(queryString["web"]);
WebId = tuple.success ? tuple.result : DefaultWebId;

Bu işe yaramaz cevaba bir sonraki işe yaramaz güncelleme C # 12'de dış parametrelerin yapısının çözülmesinden sonra gelir.


123
2018-04-13 12:18



Kesin - özlü ve tamamen istisnayı ele alma performans cezasını, program akışını kontrol etmek için kasıtlı olarak istisnalar kullanmanın kötü biçimini ve dönüşüm mantığınızın etrafa yayılmasının yumuşak odağını, birazcık burada ve biraz . - Craig
Ne demek istediğini biliyorum ama tabiki Guid.TryParse asla geri dönmez Guid.Empty. Dize yanlış bir biçimde ise, result çıkış parametresi Guid.Empty, ama o döner  false. Bahsettiğimden dolayı, bu tarz şeyler yapan bir kod gördüm. Guid.TryParse(s, out guid); if (guid == Guid.Empty) { /* handle invalid s */ }, eğer genellikle yanlış s dize temsili olabilir Guid.Empty. - hvd
Vay, soruya cevap verdin, ancak sorunun ruhu içinde değil. Büyük sorun başka bir şey :( - nawfal
TryParse'i kullanmak için uygun desen, elbette, daha çok if( Guid.TryParse(s, out guid){ /* success! */ } else { /* handle invalid s */ }Bu, giriş değerinin aslında bir Rehber'in dize temsili olabileceği bozuk örnek gibi bir belirsizlik bırakmaz. - Craig
Bu cevap Guid.Parse ile ilgili olarak gerçekten doğru olabilir, fakat asıl sorunun tüm noktasını kaçırdı. Hangi Guid.Parse ile ilgisi yoktu, ama FormatException / OverflowException / etc vs Except yakalama konusunda oldu. - Conor Gallagher


Uygulamanızı C # 6'ya yükseltebiliyorsanız şanslısınız. Yeni C # sürümü, İstisna filtrelerini uyguladı. Yani bunu yazabilirsiniz:

catch (Exception ex) when (ex is FormatException || ex is OverflowException) {
    WebId = Guid.Empty;
}

Bazı insanlar bu kodun aynı olduğunu düşünüyor

catch (Exception ex) {                
    if (ex is FormatException || ex is OverflowException) {
        WebId = Guid.Empty;
    }
    throw;
}

Ama değil. Aslında bu önceki sürümlerde taklit edilemeyen C # 6'daki yegane yeni özellik. İlk olarak, bir yeniden atma, avı tutmanın önüne geçmek için daha fazla yük demektir. İkincisi, semantik olarak eşdeğer değildir. Yeni özellik, kodunuzu hata ayıklamakta olduğunuzda yığını korur. Bu özellik olmadan, çökme boşluğu daha az faydalıdır, hatta yararsızdır.

Bkz CodePlex ile ilgili tartışma. Ve bir farkı gösteren örnek.


62
2018-04-01 12:29



İstisna olmadan atma yığını korur, ancak "eskiden atma" bunun üzerine yazacaktır. - Ivan


Eğer kullanmak istemiyorsan if içinde beyan catch kapsamları, içinde C# 6.0 kullanabilirsiniz Exception Filters sözdizimi Ön izleme sürümlerinde zaten CLR tarafından desteklenen ancak yalnızca VB.NET/MSIL:

try
{
    WebId = new Guid(queryString["web"]);
}
catch (Exception exception) when (exception is FormatException || ex is OverflowException)
{
    WebId = Guid.Empty;
}

Bu kod Exception sadece bir InvalidDataException veya ArgumentNullException.

Aslında, temelde herhangi bir koşulu koyabilirsiniz when fıkra:

static int a = 8;

...

catch (Exception exception) when (exception is InvalidDataException && a == 8)
{
    Console.WriteLine("Catch");
}

Bir aksine if içinde ifade catchkapsamı Exception Filters atılamaz Exceptionsve ne zaman yaparlarsa, ya da durum böyle değilse true, sonraki catch durum yerine değerlendirilecektir:

static int a = 7;

static int b = 0;

...

try
{
    throw new InvalidDataException();
}
catch (Exception exception) when (exception is InvalidDataException && a / b == 2)
{
    Console.WriteLine("Catch");
}
catch (Exception exception) when (exception is InvalidDataException || exception is ArgumentException)
{
    Console.WriteLine("General catch");
}

Çıkış: Genel yakalama.

Daha sonra bir tane olduğunda true  Exception Filter - ilki kabul edilecek:

static int a = 8;

static int b = 4;

...

try
{
    throw new InvalidDataException();
}
catch (Exception exception) when (exception is InvalidDataException && a / b == 2)
{
    Console.WriteLine("Catch");
}
catch (Exception exception) when (exception is InvalidDataException || exception is ArgumentException)
{
    Console.WriteLine("General catch");
}

Çıkış: Yakala.

Ve gördüğünüz gibi MSIL kod çevrildi if ifadeleri, ancak Filters, ve Exceptions ile işaretlenmiş alanlardan atılamaz Filter 1 ve Filter 2 ama filtre atıyor Exception bunun yerine başarısız olur, aynı zamanda son karşılaştırma değeri de yığına aktarılır. endfilter komut filtrenin başarısını / başarısızlığını belirler (Catch 1  XOR  Catch 2 uygun şekilde çalışacaktır):

Exception Filters MSIL

Ayrıca, özellikle Guid var Guid.TryParse yöntem.


26
2017-10-07 17:31





Kabul edilen cevap, CodeAnalysis /FxCop Genel bir istisna türü yakaladığı gerçeğini şikayet edecektir.

Ayrıca, "olduğu" operatörün performansı biraz düşürebilir gibi görünüyor.

CA1800: Gereksiz yere dökülmeyin "bunun yerine 'operatör' sonucunu test etmeyi düşünün" diyor, ancak bunu yaparsanız, her bir özel durumu ayrı ayrı yakaladığınızdan daha fazla kod yazacaksınız.

Neyse, işte yapmam gereken şey:

bool exThrown = false;

try
{
    // Something
}
catch (FormatException) {
    exThrown = true;
}
catch (OverflowException) {
    exThrown = true;
}

if (exThrown)
{
    // Something else
}

19
2017-07-30 17:09



Ancak, bunu böyle yaparsanız yığın izini kaybetmeden istisnayı yeniden yapılandıramayacağınızı unutmayın. (Michael Stum'un kabul edilen cevaba yaptığı yorumu görün) - René
Bu kalıp istisnayı saklayarak geliştirilebilir (lütfen kötü biçimlendirmeyi affedin - yorumlarda kodun nasıl yazılacağını anlayamıyorum): Exception ex = null; {// bir şeyler} catch'u deneyin (FormatException e) {ex = e; } yakalamak (OverflowException e) {ex = e; } if (ex! = null) {// başka bir şey ve ex ile anlaşma} - Jesse Weigert
@JesseWeigert: 1. Bir metin parçasını bir tek aralıklı yazı tipi ve açık gri arka planı vermek için backticks kullanabilirsiniz. 2. Orijinal istisnayı yine de yeniden atayamayacaksınız. stacktrace dahil. - Oliver
@CleverNeologism kullanarak doğru olsa da is Operatörün performans üzerinde hafif bir olumsuz etkisi olabilir, aynı zamanda bir istisna eylemcisinin performansın optimize edilmesi konusunda aşırı endişe duyan bir yer olmadığı da doğrudur. Uygulamanız, performans optimizasyonunun bu performans uygulamalarında gerçek bir fark yaratacağı istisna işleyicilerinde çok fazla zaman geçiriyorsa, o zaman zor bir bakış için diğer kod sorunları vardır. Bunu söyledikten sonra, hala bu çözümü sevmiyorum çünkü yığın izini kaybediyorsunuz ve temizleme bağlamsal olarak catch ifadesinden kaldırılıyor. - Craig
Tek zaman is Operatör performansı düşürür eğer daha sonra bir performans gösterirseniz as operasyon (dolayısıyla kural boşu boşuna). Yaptığınız tek şey oyuncu kadrosunu gerçekten yapmak zorunda kalmadan dökümünü test etmektir. is Operatör tam olarak kullanmak istediğiniz şeydir. - saluce


Bu, Matt'in cevabının bir çeşididir (bunun biraz daha temiz olduğunu hissediyorum) ... bir yöntem kullanın:

public void TryCatch(...)
{
    try
    {
       // something
       return;
    }
    catch (FormatException) {}
    catch (OverflowException) {}

    WebId = Guid.Empty;
}

Diğer istisnalar atılacak ve kod WebId = Guid.Empty; vurulmayacak. Diğer istisnaların programınızı kilitlemesini istemiyorsanız, bunu diğer iki yakalamanın ardından ekleyin:

...
catch (Exception)
{
     // something, if anything
     return; // only need this if you follow the example I gave and put it all in a method
}

18
2017-08-31 20:51



-1 Bu yürütecek WebId = Guid.Emtpy istisna olmadığı durumlarda. - Sepster
@sepster "// bir şey" den sonra geri dönüş ifadesinin burada olduğunu düşünüyorum. Çözümü gerçekten sevmiyorum ama bu tartışmada yapıcı bir varyant. Azaltmak :-) için +1 - toong
@Sepster toong haklıydı, eğer bir geri dönüş istediyseniz, o zaman bir tane koyacaksınız ... Benzer şekilde ama kesin olmayan soruları olanların başkalarının yararına olacağı durumlar için genel olarak cevabımı genel olarak yapmaya çalışıyorum. iyi. Ancak, iyi bir önlem için returncevabım Giriş için teşekkürler. - bsara


@Micheal

Kodunuzun biraz revize edilmiş hali:

catch (Exception ex)
{
   Type exType = ex.GetType();
   if (exType == typeof(System.FormatException) || 
       exType == typeof(System.OverflowException)
   {
       WebId = Guid.Empty;
   } else {
      throw;
   }
}

Dize karşılaştırmaları çirkin ve yavaştır.


17
2017-09-25 21:01



Neden "is" anahtar kelimesini kullanmıyoruz? - Chris Pietschmann
@Michael - Microsoft, FormatException'dan türetilen StringTooLongException adlı ürünü tanıttıysa, yine de yalnızca belirli bir biçim olan bir biçim istisnasıdır. 'Bu özel istisna türünü yakala' veya 'dizenin formatının yanlış olduğu anlamındaki istisnaları yakalama' semantiklerini istemeye bağlıdır. - Greg Beech
@Michael - Ayrıca, "FormatException ex" öğesinin ikinci anlambilimine sahip olduğunu, bunun FormatException'dan türetilen her şeyi yakalayacağını unutmayın. - Greg Beech
@Alex No. "throw" olmadan "ex", orijinal yığın izlemesi de dahil olmak üzere orijinal istisnayı taşır. "Ex" eklenmesi yığın izlemeyi sıfırlar, böylece orijinalden farklı bir istisna elde edersiniz. Eminim başka biri benden daha iyi anlatabilir. :) - Samantha Branham
-1: Bu kod çok kırılgandır - bir kütüphane geliştiricisi yerini almayı bekleyebilir throw new FormatException(); ile throw new NewlyDerivedFromFormatException(); kütüphaneyi kullanarak kod kırmadan ve herhangi birinin kullanıldığı durumlar haricinde tüm istisna işleme durumları için geçerli olmayacaktır. == yerine is (ya da sadece catch (FormatException)). - Sam Harwell


C # 6'da önerilen yaklaşım Özel Durum Filtrelerini kullanmaktır, burada bir örnek:

 try
 {
      throw new OverflowException();
 }
 catch(Exception e ) when ((e is DivideByZeroException) || (e is OverflowException))
 {
       // this will execute iff e is DividedByZeroEx or OverflowEx
       Console.WriteLine("E");
 }

17
2017-10-04 07:51