異常処理の検討

3075 ワード

いつ異常を使うべきか、ずっと疑問に思っていたが、「C#技術暴露」を見て、少し印象に残った.
異常処理は、エラー符号化を返すよりも、符号量を低減し、符号メンテナンスコストを低減する利点がある(もちろん、性能上の問題がある可能性があるが、これは議論の列ではない).
この点について,著者らは豊富なコードを提示し,有力な証明を行った.しかし、私を悩ませてきた異常な使い方には正面から答えられなかった.著者の多くは異常をどのように捕獲するかを議論しているが,いつ異常を放出するかはあまり議論されていない.
しかし、異常戻りエラーとエラー符号化によるエラーの比較を読むと、プログラムの実行フローをどのように制御するかを議論している興味深いものを見つけました.
例外処理プロセスの制御は、放出とキャプチャのように2つの側面に分けられます.
  • エラー(または何らかの場合)が発生した場合、プログラムの制御フローが実行を継続することを許可するかどうか(異常な放出)
  • .
  • 現在異常が発生する場合、現在のコードがプログラムの制御フローを合理的な状態(異常のキャプチャ)
  • に入る機会があるかどうか.
    以上の2つを、異常処理を判断するための目安として使えると思います.実は皆さんは今、このいわゆる準縄の重点は異常が流れに与える影響であり、どんな状況で異常を使うのではないことを発見することができるはずです.
    プロセス制御の場合、最も直接的なのは次のコードです.
    try
                        {
                            foreach (var lockGroup in lockGroups)
                            {
    
                                ...
    
                                foreach (var newlock in lockGroup.ToArray())
                                {
                                   ...
                                    if (diningBlocks.Exists(n => testLockRange.IsOverlapped(n.StartTime, n.EndTime)))
                                    {
                                        status = LockStatus.InResourceBlock;
                                        throw new LockException();
                                    }
    
                                    var diningAvail = availabilities.Find(n => n.Time == newlock.StartTime.TimeOfDay);
                                    if (diningAvail == null)
                                    {
                                        status = LockStatus.Failed;
                                        throw new LockException();
                                    }
    
    								...
    								
                                    if (newLockQuantity > diningAvail.MaxAvail && !canOverrideLock.AllowOverBook)
                                    {
                                        status = LockStatus.Override;
                                        throw new LockException();
                                    }
                                    else if (newLockQuantity + reservedQuantity + currentLockedAvail > diningAvail.MaxAvail && !canOverrideLock.AllowOverBook)
                                    {
                                        status = LockStatus.Override;
                                        throw new LockException();
                                    }
    
                                    ...
                                }
                            }
                        }
                        catch (LockException)
                        {
                            return new DiningLock[] { };
                        }

    上のコードでは、2層のforループがあり、最内層に何らかの状況が発生した場合、forループ全体の実行を停止することが要求され、明らかに2つのbreakではだめであり、補助変数を追加しなければならない.
    しかし、異常を使えば、この処理はずっと簡単です.最内層の放出異常を直接、最外層(またはプロセス制御に必要な場所)で異常をキャプチャすることができる.
    上記のコードでは,異常処理はエラー情報を伝達するだけでなく,コードの簡略化に寄与するプロセス制御の役割を果たす.