【问题标题】:Does the order matter when checking if a string isn't null and also isn't empty?检查字符串是否为空且不为空时,顺序是否重要?
【发布时间】:2019-01-25 09:52:01
【问题描述】:

我正在看一个关于 C# 三元运算符的教程,老师说你应该先检查字符串是否不为空,但没有解释原因。我试过先检查字符串是否不为空,得到的结果和他一样,有关系吗?

public class TernaryChallenge : MonoBehaviour
{
    public string playerName;
    void OnDisable()
    {
        string name = (playerName != "" && playerName != null) ? "Hello " + playerName : "Hello Player 1!";
        Debug.Log(name);
    }
}

【问题讨论】:

  • 你确定playerName在你运行上面的代码时没有一些非空值吗?如果它为空,我认为你的代码会失败。
  • 简单的回答是。使用 && 运算符时,如果第一个条件失败,则不会评估第二个条件。检查的原因是评估空指针会导致异常。

标签: c# string null conditional-statements


【解决方案1】:

不,在这种情况下,您首先检查空还是空都没有关系。您可以改用string.IsNullOrEmpty 方法并合并两个条件:

!string.IsNullOrEmpty(playerName) ? Hello " + playerName : "Hello Player 1!";

如果您正在访问字符串的属性,则顺序很重要,例如:

if(playerName.Length < 10 && playerName != null)

如果playerName 为空,这将失败,因为您试图访问空对象上的Length 属性。正确的检查方法是:

if(playerName != null && playerName.Length < 10)

或者您可以使用 C# 的 null-conditional operator 缩短它:

if(playerName?.Length < 10)

【讨论】:

  • 感谢您的回答!我很感激。你在做上帝的工作,伙计。
【解决方案2】:

这很重要,如果你在你的字符串字段上调用一个成员方法,如果它是空的,你会得到一个空引用异常。 在您的这种情况下,您可以在任何订单中检查 null 或空。

我还建议使用内置的 string.IsNullOrEmpty() 方法。请参阅以下基于您的代码编写的方法以及单元测试。

   public class TernaryChallenge
    {
        public string playerName;
        public string OnDisable1()
        {
            string name = (playerName != "" && playerName != null) ? "Hello " + 
            playerName : "Hello Player 1!";
            return name;
        }

        public string OnDisable2()
        {
            string name = (playerName != null && playerName != "") ? "Hello " + 
            playerName : "Hello Player 1!";
            return name;
        }

        public string OnDisable3()
        {
            string name = !string.IsNullOrEmpty(playerName) ? "Hello " + playerName : 
            "Hello Player 1!";
            return name;
        }

[TestMethod]
        public void TestMethod1()
        {
            var ternaryChallenge = new TernaryChallenge();

            string actual = ternaryChallenge.OnDisable1();
            string expected = "Hello Player 1!";
            Assert.AreEqual(expected, actual, ignoreCase: false);

            actual = ternaryChallenge.OnDisable2();
            expected = "Hello Player 1!";
            Assert.AreEqual(expected, actual, ignoreCase: false);

            actual = ternaryChallenge.OnDisable3();
            expected = "Hello Player 1!";
            Assert.AreEqual(expected, actual, ignoreCase: false);
        }

        [TestMethod]
        public void TestMethod2()
        {
            var ternaryChallenge = new TernaryChallenge
            {
                playerName = null
            };

            string actual = ternaryChallenge.OnDisable1();
            string expected = "Hello Player 1!";
            Assert.AreEqual(expected, actual, ignoreCase: false);

            actual = ternaryChallenge.OnDisable2();
            expected = "Hello Player 1!";
            Assert.AreEqual(expected, actual, ignoreCase: false);

            actual = ternaryChallenge.OnDisable3();
            expected = "Hello Player 1!";
            Assert.AreEqual(expected, actual, ignoreCase: false);
        }

【讨论】:

  • 在单元测试方面有点过火了......但仍然是一个正确的答案......
猜你喜欢
  • 2011-04-05
  • 2015-06-12
  • 2015-06-05
  • 1970-01-01
  • 1970-01-01
  • 2014-07-06
  • 2020-05-29
  • 2017-08-19
相关资源
最近更新 更多