2017-07-17 97 views
-2

C#問題。任意類Class的方法Foo(),可以拋出異常的方法。是否有某種方法可以將私人回撥機制bar()添加到Class,這樣如果Foo()引發異常,bar()執行將會觸發之前投擲持續上升鏈?如果這種情況不可能發生,那麼在發生異常之後怎麼辦?C#Exception Listener

- 編輯 -

由於一些初步意見是「這是混淆了你在做什麼花花公子」我會進一步解決這個問題。

我想要一個異常偵聽器的原因是因爲我有一些公開可讀的關於類Class的布爾狀態,我希望在拋出異常時將其設置爲true。由於Class中可能會有多個函數會引發異常,因此每次拋出異常時,我都不想將hasError設置爲true。自動化,寶貝。

所以我們的接口,並且主要功能有:

public interface IObjectProvider 
{ 
    IEnumerable<object> Allobjects { get; } 
} 

public interface IContext 
{ 
    delegate bool ContextIsStillValid(object o); 
    delegate void Run(object o); 
} 

// main program 
public static void Main() { 
    IContext context = initcontext(...); 
    IObjectProvider objectProvider = initobjectprovider(...); 

    // ...program executes for awhile... 

    foreach(var obj in objectProvider.AllObjects) 
    { 
     if(context.ContextIsStillValid(obj)) 
     { 
      try 
      { 
       context.Run(obj); 
      } 
      catch(Exception e) 
      { 
       // log the error 
      } 
     } 
    } 
} 

在上面的代碼片段中,我們指定一些IContext這將「運行」使用一些object當且僅當IContext第一順利通過使用相同的「驗證」檢查object。精細。現在,實現了IContext一個共同的變化是下面的(相信我的話,它是):

public class Class : IContext { 

    private bool _hasError = false; 

    // so our validation check is implemented with an internal flag. 
    // how is it set? 
    public bool ContextIsStillValid = (o) => !_hasError; 

    public void Run = 
    (o) => 
    { 
     string potentially_null_string = getstring(...); 
     if(potentially_null_string == null) 
     { 
      // our internal flag is set upon the need to throw an exception 
      this._hasError = true; 
      throw new Exception("string was null at wrong time"); 
     } 

     Global.DoSomethingWith(potentially_null_string.Split(','); 
    }; 
} 

在這裏,我們已經證明的IContext共同實施,使得一旦Run方法拋出一個ExceptionRun方法應該變得無法訪問,因爲IsContextStillValid隨後總是返回false。

現在想象在我們的Run(object)實現中還有其他異常拋出調用。問題是每次我們想要拋出一個新的異常時,我們都必須複製代碼以達到_hasError = true; throw new Exception(...);的效果。理想情況下,一個異常監聽者會爲我們解決這個問題,我很好奇你是否有人知道如何實現它。

希望有所幫助。

+0

你究竟在做什麼?你不能只用一個嘗試和重新拋出?似乎是一個奇怪的問題...... – gilmishal

+0

爲什麼不在'Foo()'中調用'try/catch',在'catch'塊中調用'bar()',然後重新拋出? – David

+0

您可以在技術上使用catch塊上的異常過濾器來觀察異常,然後調用堆棧解除展開。有關示例,請參閱[例外過濾器]上的SO文檔(https://stackoverflow.com/documentation/c%23/24/c-sharp-6-0-features/46/exception-filters)。 –

回答

0
public class MyClass 
{ 
    public void Foo() 
    { 
     try 
     { 
      //Execute some code that might fail 
     } 
     catch 
     { 
      bar(); 
      throw; 
     } 
    } 
    private void bar() 
    { 
     //do something before throwing 
    } 
} 
+0

我想補充一點,還需要考慮bar()本身的執行可能會引發錯誤的事實。 – JuanR

+0

的確,這一切都取決於你在做什麼以及你希望如何表現。 –

+0

@CavanPage謝謝Cavan,這個建議已經提出,這個建議可能會起作用,我很欣賞你的意見。 –