gpt4 book ai didi

c#异常处理,实际例子。你会怎么做?

转载 作者:可可西里 更新时间:2023-11-01 08:02:10 24 4
gpt4 key购买 nike

我正在尝试更好地处理异常,但我觉得当我尽我最大努力捕捉它们时,我的代码变得非常丑陋、不可读和困惑。我很想看看其他人如何通过提供实际示例和比较解决方案来解决这个问题。

我的示例方法从 URL 下载数据并尝试将其序列化为给定类型,然后返回一个填充了数据的实例。

首先,完全没有任何异常处理:

    private static T LoadAndSerialize<T>(string url)
{
var uri = new Uri(url);
var request = WebRequest.Create(uri);
var response = request.GetResponse();
var stream = response.GetResponseStream();

var result = Activator.CreateInstance<T>();
var serializer = new DataContractJsonSerializer(result.GetType());
return (T)serializer.ReadObject(stream);
}

我觉得这个方法像这样可读性很好。我知道该方法中有一些不必要的步骤(例如 WebRequest.Create() 可以采用字符串,并且我可以在不给它们变量的情况下链接方法)但我会像这样保留它以便更好地与异常版本进行比较 -处理。

这是处理所有可能出错的事情的第一次尝试:

    private static T LoadAndSerialize<T>(string url)
{
Uri uri;
WebRequest request;
WebResponse response;
Stream stream;
T instance;
DataContractJsonSerializer serializer;

try
{
uri = new Uri(url);
}
catch (Exception e)
{
throw new Exception("LoadAndSerialize : Parameter 'url' is malformed or missing.", e);
}

try
{
request = WebRequest.Create(uri);
}
catch (Exception e)
{
throw new Exception("LoadAndSerialize : Unable to create WebRequest.", e);
}

try
{
response = request.GetResponse();
}
catch (Exception e)
{
throw new Exception(string.Format("LoadAndSerialize : Error while getting response from host '{0}'.", uri.Host), e);
}

if (response == null) throw new Exception(string.Format("LoadAndSerialize : No response from host '{0}'.", uri.Host));

try
{
stream = response.GetResponseStream();
}
catch (Exception e)
{
throw new Exception("LoadAndSerialize : Unable to get stream from response.", e);
}

if (stream == null) throw new Exception("LoadAndSerialize : Unable to get a stream from response.");

try
{
instance = Activator.CreateInstance<T>();
}
catch (Exception e)
{
throw new Exception(string.Format("LoadAndSerialize : Unable to create and instance of '{0}' (no parameterless constructor?).", typeof(T).Name), e);
}

try
{
serializer = new DataContractJsonSerializer(instance.GetType());
}
catch (Exception e)
{

throw new Exception(string.Format("LoadAndSerialize : Unable to create serializer for '{0}' (databinding issues?).", typeof(T).Name), e);
}


try
{
instance = (T)serializer.ReadObject(stream);
}
catch (Exception e)
{
throw new Exception(string.Format("LoadAndSerialize : Unable to serialize stream into '{0}'.", typeof(T).Name), e);
}

return instance;
}

这里的问题是,虽然所有可能出错的东西都会被捕获并给出一个有点有意义的异常,但这是一个相当大的困惑局面。

那么,如果我改为链式捕获呢?我的下一次尝试是:

    private static T LoadAndSerialize<T>(string url)
{
try
{
var uri = new Uri(url);
var request = WebRequest.Create(uri);
var response = request.GetResponse();
var stream = response.GetResponseStream();
var serializer = new DataContractJsonSerializer(typeof(T));
return (T)serializer.ReadObject(stream);
}
catch (ArgumentNullException e)
{
throw new Exception("LoadAndSerialize : Parameter 'url' cannot be null.", e);
}
catch (UriFormatException e)
{
throw new Exception("LoadAndSerialize : Parameter 'url' is malformed.", e);
}
catch (NotSupportedException e)
{
throw new Exception("LoadAndSerialize : Unable to create WebRequest or get response stream, operation not supported.", e);
}
catch (System.Security.SecurityException e)
{
throw new Exception("LoadAndSerialize : Unable to create WebRequest, operation was prohibited.", e);
}
catch (NotImplementedException e)
{
throw new Exception("LoadAndSerialize : Unable to get response from WebRequest, method not implemented?!.", e);
}
catch(NullReferenceException e)
{
throw new Exception("LoadAndSerialize : Response or stream was empty.", e);
}
}

虽然看起来确实更容易,但我在这里非常依赖智能感知来提供可能从方法或类中抛出的所有异常。我不相信此文档是 100% 准确的,如果某些方法来自 .net 框架之外的程序集,我会更加怀疑。例如,DataContractJsonSerializer 在智能感知上没有显示异常。这是否意味着构造函数永远不会失败?我可以确定吗?

与此相关的其他问题是某些方法抛出相同的异常,这使得错误更难描述(这个或这个或这个出错了),因此对用户/调试器来说用处不大。

第三种选择是忽略所有异常,除了允许我采取重试连接等操作的异常。如果 url 为空,则 url 为空,捕获的唯一好处是更详细的错误消息。

我很乐意看到您的想法和/或实现!

最佳答案

异常处理规则之一 - 不要捕获您不知道如何处理的异常。

仅仅为了提供漂亮的错误消息而捕获异常是有问题的。异常类型和消息已包含足够的信息供开发人员使用 - 您提供的消息不会增加任何值(value)。

the DataContractJsonSerializer show no exceptions on the intellisense. Does this mean the constructor will never fail? Can I be sure?

不,你不能确定。 C# 和 .NET 通常不像 Java,您必须声明可能抛出的异常。

A third option would be to ignore all exceptions apart from the ones that would allow me to take an action like retrying the connection.

这确实是最好的选择。

您还可以在应用程序顶部添加一个通用异常处理程序,它将捕获所有未处理的异常并记录它们。

关于c#异常处理,实际例子。你会怎么做?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9708929/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com