c#如何在不使用try catch直接代码的情况下处理Null Exception?

时间:2014-02-26 23:11:03

标签: c#-4.0

我正在尝试编写更好的代码而不使用try catch来直接代码而不使用空捕获但是我很难。

这是我的代码片段

    public static List<string> GetProcessList()
    {
        List<string> result = new List<string>();
        foreach (AudioSession session in AudioUtilities.GetAllSessions())
        {

            try
            {
                if (session != null && session.Process != null && !String.IsNullOrEmpty(session.Process.ProcessName))
                {
                    result.Add(session.Process.ProcessName);

                }
            }
            catch (Exception ex)
            {

                LogManager.Instance().TbLogger.LogError("GetAllSessions " + ex.StackTrace);
                ex.ToExceptionless().Submit();
            }

        }

        return result;
    }

如何重写它,看起来不像这样。

    public static List<string> GetProcessList()
    {
        List<string> result = new List<string>();
        foreach (AudioSession session in AudioUtilities.GetAllSessions())
        {

            try
            {
                if (session != null && session.Process != null && !String.IsNullOrEmpty(session.Process.ProcessName))
                {
                    result.Add(session.Process.ProcessName);

                }
            }
            catch (System.NullReferenceException)
            {
                //don't add to the list
                //can this empty catch be avoided?
            }
            catch (Exception ex)
            {

                LogManager.Instance().TbLogger.LogError("GetAllSessions " + ex.StackTrace);
                ex.ToExceptionless().Submit();
            }

        }

        return result;
    }

或者喜欢这个......

    public static List<string> GetProcessList()
    {
        List<string> result = new List<string>();
        foreach (AudioSession session in AudioUtilities.GetAllSessions())
        {

            try
            {
                if (session != null && session.Process != null && !String.IsNullOrEmpty(session.Process.ProcessName))
                {
                    result.Add(session.Process.ProcessName);

                }
            }
            catch (Exception ex)
            {
               //do nothing
            }

        }

        return result;
    }

更新:抱歉,我忘了添加我遇到的错误...

这是堆栈跟踪。

System.NullReferenceException: Object reference not set to an instance of an object.
at myControl.AudioUtilities.GetAllSessions()

如何正确重写此功能?

提前致谢

2 个答案:

答案 0 :(得分:0)

如果您在访问之前使用comparatos检查引用是否为null,则永远不会出现异常。

public static List<string> GetProcessList()
{
    List<string> result = new List<string>();
    foreach (AudioSession session in AudioUtilities.GetAllSessions())
    {
        if(session == null || session.Process == null || String.IsNullOrEmpty(session.Process.ProcessName))
            continue;

        result.Add(session.Process.ProcessName);
    }

    return result;
}

除非你的GetAllSessions方法正在抛出异常 - 但它不在try clausule中。

答案 1 :(得分:0)

在查找空引用时,您可以检查每个'。'和功能*。以下是您的代码中的内容:

  • AudioUtilities.GetAllSessions(),AudioUtilities是一个类型,一个实例变量,还是一个静态变量?
  • session.Process,但在此之前检查会话是否为空。
  • session.Process.ProcessName,但在此之前检查session.Process为空。
  • result.Add(...),但您在此处初始化了结果。
  • result.Add(session.Process.ProcessName),但在此之前检查session.Process.ProcessName是否为空。

所以,除了AudioUtilities.GetAllSessions()之外,你已经涵盖了可能导致这种情况的所有地方,以及是否可以在另一个线程上修改其中任何一个。如果是这种情况,您可以在测试之前存储每个值为null:

    public static List<string> GetProcessList()
    {
        List<string> result = new List<string>();

        List<AudioSession> sessions = null;
        if (AudioUtilities != null)
            sessions = AudioUtilities.GetAllSessions();

        if (sessions != null)
        {
            foreach (AudioSession session in sessions)
            {
                Process process = null; //guessing type here
                if (session != null)
                    process = session.Process;
                string processName = null;
                if (process != null)
                    processName = process.ProcessName;

                if (processName != null)
                    result.Add(processName);
            }
        }

        return result;
    }

这看起来有点矫枉过正,但应该是安全的。这可以保护您免受(检查不太可能)检查和取消引用之间数据更改的事件的影响。

*除非我忘记了什么,虽然我在这里看不到任何适用的东西。