C# 对空合并运算符求反

C# 对空合并运算符求反,c#,null-coalescing-operator,C#,Null Coalescing Operator,我有一大堆字符串需要使用.Trim(),但它们可以为null。如果我能做到以下几点,它会更加简洁: string endString = startString !?? startString.Trim(); 如果左边的部分不为null,则基本上返回右边的部分,否则只返回null值。我只是使用了三元运算符,但是否有必要为此使用空合并运算符 string endString = string.IsNullOrEmpty(startString) ? startString : startStri

我有一大堆字符串需要使用.Trim(),但它们可以为null。如果我能做到以下几点,它会更加简洁:

string endString = startString !?? startString.Trim();
如果左边的部分不为null,则基本上返回右边的部分,否则只返回null值。我只是使用了三元运算符,但是否有必要为此使用空合并运算符

string endString = string.IsNullOrEmpty(startString) ? startString : startString.Trim();
尽管我也写了一个名为“safeTrim”的字符串扩展方法,它可以实现您在一个方法中描述的功能,而不是每次都使用这个方法。查看代码

编辑:哇,我有各种各样的向后的、命名错误的变量和反向的三元运算符,更有理由编写一个扩展方法和代码,比我做得更好

使用

string endString = (startString ?? "").Trim();
如果startString为null,则使用empy字符串。但是,当
endString
为null时,不会返回null

快进到2021年:

10年后
startString?.Trim()
无疑是更好的选择。这个确实返回了
null

而不是规范:不是我喜欢的,但是您可以使用:

string endString = (startString ?? String.Empty).Trim();
根据规范,作为@Kevin的扩展方法更好:

string endString = (startString == null ? null : startString.Trim());

您可以创建一个扩展方法,该方法在尝试修剪值时返回
null

public String TrimIfNotNull(this string item)
{
   if(String.IsNullOrEmpty(item))
     return item;
   else
    return item.Trim();
}

注意,您不能将其命名为Trim,因为扩展方法不能覆盖实例方法。

以下内容不传播null,但它接受null作为参数,并在这种情况下返回空字符串

using Microsoft.VisualBasic;  // you need to add a reference to Microsoft.VisualBasic.dll

    ...
    string endString = Strings.Trim(startString);
    ...

duck&run…

作为旁注,如果您使用的是.NET 4,那么您可以使用一种新的方便方法。

很抱歉进行巫术,但我遇到了同样的问题,我使用lambda操作解决了这个问题。它不是最漂亮的,但它使我的代码简洁

遗憾的是,C#不支持静态导入或单个函数导入,但无论如何:

在某处定义此函数:

private static TResult N<TParent,TResult>(TParent parent, Func<TParent,TResult> operation) {
    if( parent == null ) return default(TResult);
    return operation( parent );
}
如果第一个参数为null,则
N
函数返回
null
,否则它将使用该值作为参数计算指定的lambda函数

当然,你可以像这样把它套起来。例如,为了安全地解除对长链的引用,例如

String someValue = someObject.SomeProperty.SomeOtherProperty.SomeMethod().SomeFinalProperty;
如果这些属性或方法中的任何一个返回null,则必须在所有位置插入null检查,或者可以执行以下操作:

String someValue = N(N(N(N(someObject, o => o.SomeProperty), o => o.SomeOtherProperty), o => o.SomeMethod()), o => o.SomeFinalProperty);
正如我所说,它不是最漂亮的:)

您可以通过使
N
成为
System.Object
的扩展方法来简化此过程,如下所示:

String someValue = someObject.N( o => o.SomeProperty ).N( o => o.SomeOtherProperty ).N( o => o.SomeMethod() ).N( o => o.SomeFinalProperty );
…我认为这要整洁得多。

从C#6.0(.NET Framework 4.6/Visual Studio 2015)开始,您可以使用:



我不这么认为,
有什么问题吗!string.IsNullOrEmpty(startString)?startString.Trim():null空字符串时,即使startString为null。听起来你真正想要的是
?。:
三元运算符;如果左侧操作数为非null,则访问相应的成员,否则计算右侧。示例用法:
theValue=someThing?.SomeProperty:defaultValue;
这将是一个有用的运算符,但它的语法和绑定将完全不同于该语言中的任何其他运算符。Ninja-edited感谢Frank的评论提醒我它是
string.IsNullOrEmpty(foo)
而不是
foo.IsNullOrEmpty()
检查是否为空。这不是他所要求的,如果在这个特定语句中定义了
endString
,它怎么可能已经在范围内了?我想你需要做更多的忍者编辑…我想你的意思是
string endString=string.IsNullOrEmpty(startString)?startString:startString.Trim()
。如果null/empty,他想要null字符串,如果它不是null/empty,他想要修剪它。@Sarah确实这样做了,我做得非常倒退,甚至为一个分支选择了错误的变量名。wow HeadDesk不会像他要求的那样传播null。如果startString为null,他不会返回null。我花了第二次阅读才意识到这一点他实际上想要空的…@Kevin在这种情况下的想法是正确的。为什么不使用
string.IsNullOrEmpty()呢
?我收集到,他希望null保持为null,empty保持为空。如果startString为null,他希望endString为null。您的示例将返回string.EmptyInteresting方法,但似乎与OP的问题正交。当
为null时,这感觉非常错误……但是,我确实确认它有效。
string s=null;s.TrimIfNotNull();
No
NullReferenceException
与常规实例方法(即使是不引用任何成员的方法)一样。它的工作原理非常合理。扩展方法只不过是附加到对象上的静态方法。实际上,它们没有理由不工作。类不能依赖于它们所做的任何事情,因为它们不是在原始类创建时创建的,并且它们不能访问任何私有方法或对象。这将是的,该特性的高潮是IfNotNull扩展方法:
public V IfNotNull(这个T@in,Func访问)
类约束泛型似乎比
System.Object
更好,我认为最好有一些接受不同数量“额外”参数的变体。必须
String someValue = someObject.N( o => o.SomeProperty ).N( o => o.SomeOtherProperty ).N( o => o.SomeMethod() ).N( o => o.SomeFinalProperty );
 string? endString = startString?.Trim();