使用派生类型调用扩展方法的重载

简化,我有这两种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 个根据异常类型调用扩展的捕获。


有没有办法在运行时调用正确的扩展方法?


冉冉说
浏览 209回答 2
2回答

海绵宝宝撒

正如 Yacoub Massad 建议您可以使用dynamic,因为dynamic方法重载解析在运行时通过后期绑定推迟:public static class Extensions{&nbsp; &nbsp; public static string GetString<T>(this T e) where T : Exception&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; // dynamic method overload resolution is deferred at runtime through late binding.&nbsp; &nbsp; &nbsp; &nbsp; return GetStringCore((dynamic)e);&nbsp; &nbsp; }&nbsp; &nbsp; static string GetStringCore(Exception e)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return "Standard!!!";&nbsp; &nbsp; }&nbsp; &nbsp; static string GetStringCore(TimeoutException e)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return "TimeOut!!!";&nbsp; &nbsp; }&nbsp; &nbsp; static string GetStringCore(InvalidOperationException e)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return "Invalid!!!";&nbsp; &nbsp; }}这应该可以解决问题。

慕姐4208626

扩展方法在这里是错误的工具。我会提倡使用多态来解决您的问题:public abstract class BaseException : Exception{&nbsp; &nbsp; public abstract string GetString();}public sealed class TimeoutException : BaseException{&nbsp; &nbsp; public override string GetString() => "TimeOut!!!";}public sealed class MyException : BaseException{&nbsp; &nbsp; public override string GetString() => "Standard!!!";}用法try{&nbsp; &nbsp; throw new TimeoutException(); //or whatever BaseException's children}catch (BaseException e){&nbsp; &nbsp; //here I'm assuming you know that you are swallowing the exception (which may be an anti-pattern)&nbsp; &nbsp; Console.WriteLine(e.GetString());}编辑看起来您无法完全控制引发异常的时间和地点。另一种可能性是为每个行为(而不是每个异常类型)添加 1 个 catch 子句并删除GetString():try{&nbsp; &nbsp; throw new TimeoutException();}catch (Exception e) when (e is ArgumentNullException || e is FormatException){&nbsp; &nbsp; //do something}catch (Exception e) when (e is TimeoutException){&nbsp; &nbsp; //do something}catch (Exception e){&nbsp; &nbsp; throw new NotImplementedException($"Hey Mike, write something for {e.GetType()}, will ya?"); //idea from Jeroen}
打开App,查看更多内容
随时随地看视频慕课网APP