亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用派生類型調用擴展方法的重載

使用派生類型調用擴展方法的重載

C#
冉冉說 2021-07-14 17:05:53
簡化,我有這兩種Extension方法:public static class Extensions{    public static string GetString(this Exception e)    {        return "Standard!!!";    }    public static string GetString(this TimeoutException e)    {        return "TimeOut!!!";    }}這是我使用它們的地方:try{    throw new TimeoutException();}catch (Exception e){    Type t = e.GetType(); //At debugging this a TimeoutException    Console.WriteLine(e.GetString()); //Prints: Standard}我有更多的GetString()擴展。我try{...}catch{...}的越來越大,基本上我正在尋找方法將其縮短為 1 個根據異常類型調用擴展的捕獲。有沒有辦法在運行時調用正確的擴展方法?
查看完整描述

2 回答

?
海綿寶寶撒

TA貢獻1809條經驗 獲得超8個贊

正如 Yacoub Massad 建議您可以使用dynamic,因為dynamic方法重載解析在運行時通過后期綁定推遲:


public static class Extensions

{

    public static string GetString<T>(this T e) where T : Exception

    {

        // dynamic method overload resolution is deferred at runtime through late binding.

        return GetStringCore((dynamic)e);

    }


    static string GetStringCore(Exception e)

    {

        return "Standard!!!";

    }


    static string GetStringCore(TimeoutException e)

    {

        return "TimeOut!!!";

    }


    static string GetStringCore(InvalidOperationException e)

    {

        return "Invalid!!!";

    }

}

這應該可以解決問題。


查看完整回答
反對 回復 2021-07-17
?
慕姐4208626

TA貢獻1852條經驗 獲得超7個贊

擴展方法在這里是錯誤的工具。


我會提倡使用多態來解決您的問題:


public abstract class BaseException : Exception

{

    public abstract string GetString();

}


public sealed class TimeoutException : BaseException

{

    public override string GetString() => "TimeOut!!!";

}


public sealed class MyException : BaseException

{

    public override string GetString() => "Standard!!!";

}

用法


try

{

    throw new TimeoutException(); //or whatever BaseException's children

}

catch (BaseException e)

{

    //here I'm assuming you know that you are swallowing the exception (which may be an anti-pattern)

    Console.WriteLine(e.GetString());

}

編輯

看起來您無法完全控制引發異常的時間和地點。另一種可能性是為每個行為(而不是每個異常類型)添加 1 個 catch 子句并刪除GetString():


try

{

    throw new TimeoutException();

}

catch (Exception e) when (e is ArgumentNullException || e is FormatException)

{

    //do something

}

catch (Exception e) when (e is TimeoutException)

{

    //do something

}

catch (Exception e)

{

    throw new NotImplementedException($"Hey Mike, write something for {e.GetType()}, will ya?"); //idea from Jeroen

}


查看完整回答
反對 回復 2021-07-17
  • 2 回答
  • 0 關注
  • 234 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號