C#中的异常处理,实际的例子。你会怎么做呢? [英] c# exception handling, practical example. How would you do it?

查看:143
本文介绍了C#中的异常处理,实际的例子。你会怎么做呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图让在处理异常的好,但我觉得我的代码变得非常难看,无法读取和凌乱,当我尽我所能,抓住他们。我很想看到其他人如何处理这通过给一个实际的例子和比较的解决方案。

I'm trying to get better at handling exceptions but I feel like my code gets very ugly, unreadable and cluttered when I try my best to catch them. I would love to see how other people approach this by giving a practical example and compare solutions.

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

My example method downloads data from an URL and tries to serialize it into a given type, then return an instance populated with the data.

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

First, without any exception-handling at all:

    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()可以接受字符串,我可以链的方法,而没有给他们的变量)有,但我会离开它像这样能够更好地比较的同在与异常版本。处理

I feel like the method is fairly readable like this. I know there are a few unnecessary steps in the method (like WebRequest.Create() can take a string, and I could chain methods without giving them variables) there but I will leave it like this to better compare against the version with exception-handling.

这是处理一切可能出问题的第一次尝试:

This is an first attempt to handle everything that could go wrong:

    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;
    }



这里的问题是,尽管一切可能出问题将被捕获并给出一个有点意义的例外,它是显著比例的杂波巨星。

The problem here is that while everything that could possibly go wrong will be caught and given a somewhat meaningful exception, it is a clutter-fest of significant proportions.

所以,如果我不是链的醒目。我的下一个尝试是这样的:

So, what if I chain the catching instead. My next attempt is this:

    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显示在智能感知没有例外。这是否意味着构造永远不会失败?我可以肯定的?

While it certainly is easier on the eyes, I am leaning heavily the intellisense here to provide all exceptions that can possibly be thrown from a method or class. I don't feel confident that this documentation is 100% accurate, and would be even more skeptical if some of the methods came from an assembly outside the .net framework. As an example the DataContractJsonSerializer show no exceptions on the intellisense. Does this mean the constructor will never fail? Can I be sure?

本的其他问题是,一些方法抛出同样的异常,这使得错误更难描述(这或本或本出了错)等是用户/调试器的那么有用。

Other issues with this is that some of the methods throw the same exception, which makes the error harder to describe (this or this or this went wrong) and so is less useful to the user / debugger.

第三个选择是从的人,让我拿一样重试动作除了忽略所有异常连接。如果url为null,则该URL为null,从追赶,唯一的好处是一点点更详细的错误信息。

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. If the url is null then the url is null, the only benefit from catching that is a little bit more verbose error message.

我很想看到你的想法和/或实施

I would love to see your thoughts and/or implementations!

推荐答案

的异常处理法则一 - !不抓你不知道如何处理异常。

Rule one of exception handling - do not catch exceptions you don't know how to handle.

只是为了提供漂亮的错误信息捕获异常是值得商榷的。异常类型和消息已经包含了的足够的信息,开发者的 - 您提供的不添加任何价值的消息

Catching exceptions just in order to provide nice error messages is questionable. The exception type and message already contain enough information for a developer - the messages you have provided do not add any value.

在DataContractJsonSerializer显示在智能感知没有例外。这是否意味着构造永远不会失败?我可以肯定的?

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

没有,你不能确定。 C#和.NET中一般不喜欢的Java,你的有无的声明可能会抛出什么异常。

No, you can't be sure. C# and .NET in general are not like Java where you have to declare what exceptions may be thrown.

第三个选择是从的人,让我拿一样重试动作的连接除了忽略所有异常。

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.

这的确是最好的选择。

That indeed is the best option.

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

You can also add a general exception handler at the top of the application that will capture all unhandled exceptions and log them.

这篇关于C#中的异常处理,实际的例子。你会怎么做呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆