19

现在 c# 中是否有任何简写可以减少以下代码:

var testVar1 = checkObject();
if (testVar1 != null)
{
      testVar2 = testVar1;
}

在这种情况下,如果 testVar1 从 CheckObject() 结果中不为空,则只想分配 testVar2(testVar2 有一个将触发代码的设置器)。试图思考如何使用空合并的东西,但没有真正解决。

添加到这个 testVar2 的 setter 上有代码可以触发,所以如果值为 null,不希望 testVar2 被设置为任何值。

    public MyObj testVar2
    {
        get { return _testVar2; }
        set
        {
            _testVar2 = value;
            RunSomeCode();                
        }
    }
4

5 回答 5

25

有一对!

三元运算符:

testvar2 = testVar1 != null ? testvar1 : testvar2;

将是完全相同的逻辑。

或者,如评论所述,您可以使用空合并运算符:

testVar2 = testVar1 ?? testVar2

(虽然现在这也被评论了)

或者第三种选择:编写一次方法并按照您的喜好使用它:

public static class CheckIt
{
    public static void SetWhenNotNull(string mightBeNull,ref string notNullable)
    {
        if (mightBeNull != null)
        {
            notNullable = mightBeNull;
        }
    }
}  

并称之为:

CheckIt.SetWhenNotNull(test1, ref test2);
于 2019-06-06T22:05:15.437 回答
10

不是问题的答案,但我用谷歌搜索了“ c# shorthand set if null ”并首先登陆这里,所以只是为了其他人。问题是“if NOT null 然后赋值的简写”,下面是“if null 然后赋值的简写”。

在 C# 8.0+ 中,您可以使用??=

// Assign testVar1 to testVar2, if testVar2 is null
testVar2 ??= testVar1;

// Which is the same as:
testVar2 = testVar2 ?? testVar1;

// Which is the same as:
if(testVar2 == null)
{
   testVar2 = testVar1;
}

还有我最喜欢的:

// Create new instance if null:
testVar1 ??= new testClass1();

// Which is the same as:
if(testVar1 == null)
{
   testVar1 = new testClass1();
}

只是我经常使用的一个例子:

List<string> testList = null;

// Add new test value (create new list, if it's null, to avoid null reference)
public void AddTestValue(string testValue)
{
   testList ??= new List<string>();
   testList.Add(testValue);
}
于 2020-05-21T22:10:33.543 回答
2

你提到testVar2有一个设置器在设置时触发一些事件。如果您不检查testVar2是否设置为自身,则事件仍将使用空合并运算符(或三元运算符)触发。

我认为您要么必须testVar2在其设置器中检查是否被设置为自身,要么执行您现在正在做的事情。

    public MyObj testVar2
    {
        get { return _testVar2; }
        set
        {
            if (_testVar2 != value)
            {
               _testVar2 = value;
               RunSomeCode();
            }                
        }
    }

我认为这完全是我的意见,但我会把它留给你现在的样子。我认为它比速记更能传达意图。

testVar2 = testVar1 ?? tesrVar2说,“设置testVar2testVar1。除非testVar1为空。然后设置testVar2testVar2”。

if (testVar1 != null)
{
   testVar2 = testVar1;
}

说,“如果testVar1不为空,设置testVar2testVar1”。

于 2019-06-06T22:12:25.763 回答
2

您可以使用null-coalescing 运算符,如下所示testVar2 = testVar1 ?? testVar2:如果为空,您可以将其替换?? testVar2为您想要设置的任何内容。testVar1

于 2019-06-06T22:06:04.863 回答
1

如果您不想让 testVar2 设置为null,那么null在 setter 本身中进行检查可能更有意义。否则,您必须记住在null尝试设置它的任何时候检查。

请注意,我还修改了大小写以符合 C# 标准

private MyObj testVar2;

public MyObj TestVar2
{
    get { return testVar2; }
    set
    {
        if (value == null) return;      // Or throw an ArgumentNullException
        if (testVar2 == value) return;  // No need to RunSomeCode if the value isn't changing

        testVar2 = value;
        RunSomeCode();                
    }
}

现在,如果您仍然关心null在设置属性之前进行检查(例如,如果您决定在值的情况下抛出异常null),那么您的原始代码没有任何问题(三元/空合并解决方案以某种方式看起来“浪费”,因为他们可能会为自己设置一些东西),你可以在一行中做到这一点:

if (testVar1 != null) SomeClass.TestVar2 = testVar1;

但是,如果您只是testVar1为了捕获调用结果而创建CheckObject(),那么 null 合并运算符会更有意义,因为您不必创建变量来存储值:

SomeClass.TestVar2 = CheckObject() ?? SomeClass.TestVar2;
于 2019-06-06T22:28:49.470 回答