string.IsNullOrEmpty()似乎并不在类中的处理字符串类中类中、字符串、string、IsNullOrEmpty

2023-09-07 08:43:38 作者:孤城傲影

首先,我想我知道这是怎么回事,但我想我会提出这一问题,这里的一些讨论,看看是否有人有一个答案这个以外我在想什么。因为,它没有完全意义的我。

First off, I think I know what's going on, but I thought I'd bring this issue up here for some discussion and see if anyone has an "answer" to this other than what I'm thinking. Because, it doesn't completely make sense to me.

我发现的是,创造一个例外错误日志的时候,我是这样做的,这是不工作:

What I found is that when creating a error log for exceptions, I was doing this and it wasn't working:

catch( Exception ex )
{
   LogException( ex.Message );
   if ( !string.IsNullOrEmpty( ex.InnerException.Message ) )
   {
      LogInnerException( ex.InnerException.Message );
   }
}

和你瞧,当我跑这个,我会经常收到一个NullReferenceException。咦?

and lo and behold, when I ran this I'd often get a NullReferenceException. Huh?

我检查空,对吧?

现在,我不得不使用这样的:

now, I have to use this:

   if ( ex.InnerException != null && !string.IsNullOrEmpty( ex.InnerException.Message ) 

但似乎违反直觉的,也是适得其反。因为,哎呀,如果我这样做:

but that seems counter-intuitive and also counter productive. Because, heck, if I do this:

   if ( !string.IsNullOrEmpty( null ) )

这并没有给我任何问题都没有。如果ex.InnerException为空的话,肯定ex.InnerException.Message为空,对吧?

That doesn't give me any problems at all. And if ex.InnerException is null, then certainly ex.InnerException.Message is null, right?

显然不是。

我写了一个完整的控制台应用程序重现此。如果您

I wrote a complete console app that reproduces this. If you

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace stringisnullorempty
{
    class Program
    {
        static void Main( string[] args )
        {
            if ( !string.IsNullOrEmpty( null ) )
            {
                Console.WriteLine( "Ha ha ha, right...." );
            }

            MyBClass bClass = new MyBClass();
            bClass.BClassName = "Some B Class Name";
            if ( !string.IsNullOrEmpty( bClass.AClass.AString ) ) //<== Exception occurs here.
            {
                Console.WriteLine( bClass.AClass.AString );
            }
        }
    }

    public class MyAClass
    {
        private string aString;
        public string AString
        {
            get
            {
                return aString;
            }
            set
            {
                aString = value;
            }
        }

        private int aValue;
        public int AValue
        {
            get
            {
                return aValue;
            }
            set
            {
                aValue = value;
            }
        }

        public MyAClass() { }
    }

    public class MyBClass
    {
        private MyAClass aClass;
        public MyAClass AClass
        {
            get
            {
                return aClass;
            }
            set
            {
                aClass = value;
            }
        }

        private string bClassName;
        public string BClassName
        {
            get
            {
                return bClassName;
            }
            set
            {
                bClassName = value;
            }
        }
        public MyBClass() { }
    }
}

我认为正在发生的事情是,code尝试处理IsNullOrEmpty之前处理ex.InnerException.Message。由于ex.InnerException为空,我们得到一个异常尝试访问ex.InnerException.Message。

What I think is happening is that the code processes ex.InnerException.Message before trying to process the IsNullOrEmpty. Since ex.InnerException is null, we get an exception trying to access ex.InnerException.Message.

我想知道,不过,我需要完整的检查?请问ex.InnerException!= NULL是不够的。如果我们有一个内部异常,将我们总是有一个与之关联的消息?

I'm wondering though, do I need the full check? Will the ex.InnerException != null be enough. If we have an inner exception, will we always have a message associated with it?

感谢。

推荐答案

当你调用 ex.InnerException.Message ,它不是为空的消息,而随后的InnerException 对象。

When you call ex.InnerException.Message, it's not the message that is null, but rather then InnerException object.

考虑一下这种方式:

string temp = ex.InnerException.Message
              //               ^ the error is on this dot.
if (string.IsNullOrEmpty(temp))
{
    ...
}

要正是你想做的事搭配,只需要使用这样的:

To match exactly what you want to do, just use this:

catch (Exception ex)  // PLEASE catch something more specific.
{
   LogException(ex.Message);
   if (ex.InnerException != null)
   {
      LogInnerException(ex.InnerException.Message);
   }
}

为了解决这个问题,我已经使用这个方法过去:

In order to solve this problem, I have used this method in the past:

public Exception GetInnermost(Exception ex)
{
    while (ex.InnerException != null) ex = ex.InnerException;
    return ex;
}

ex.GetBaseException()