C# 对空合并运算符求反
我有一大堆字符串需要使用.Trim(),但它们可以为null。如果我能做到以下几点,它会更加简洁: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
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我理解您的问题,您希望传播null,即如果字符串为null,则返回null。否则,重新运行修剪过的字符串。对吗?如果是这种情况,则没有内置的运算符或方法来执行此操作。您可以使用三元运算符(如您所做)或编写方法。我仍在等待此运算符成为语言的一部分:(我喜欢@sixlettervariables方法,当我们需要返回空字符串时,即使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();
NoNullReferenceException
与常规实例方法(即使是不引用任何成员的方法)一样。它的工作原理非常合理。扩展方法只不过是附加到对象上的静态方法。实际上,它们没有理由不工作。类不能依赖于它们所做的任何事情,因为它们不是在原始类创建时创建的,并且它们不能访问任何私有方法或对象。这将是的,该特性的高潮是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();