C# 使用 Null Coalescing 运算符的独特方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/278703/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Unique ways to use the Null Coalescing operator
提问by Armstrongest
I know the standard way of using the Null coalescing operator in C# is to set default values.
我知道在 C# 中使用 Null 合并运算符的标准方法是设置默认值。
string nobody = null;
string somebody = "Bob Saget";
string anybody = "";
anybody = nobody ?? "Mr. T"; // returns Mr. T
anybody = somebody ?? "Mr. T"; // returns "Bob Saget"
But what else can ??
be used for? It doesn't seem as useful as the ternary operator, apart from being more concise and easier to read than:
但是还能??
用来做什么呢?它似乎不如三元运算符有用,除了比以下内容更简洁易读之外:
nobody = null;
anybody = nobody == null ? "Bob Saget" : nobody; // returns Bob Saget
So given that fewer even know about null coalescing operator...
因此,鉴于很少有人知道空合并运算符......
Have you used
??
for something else?Is
??
necessary, or should you just use the ternary operator (that most are familiar with)
你用过
??
别的吗?是
??
必要的,还是应该只使用三元运算符(大多数人都熟悉)
采纳答案by James Curran
Well, first of all, it's much easier to chain than the standard ternary:
嗯,首先,它比标准的三元更容易链接:
string anybody = parm1 ?? localDefault ?? globalDefault;
vs.
对比
string anyboby = (parm1 != null) ? parm1
: ((localDefault != null) ? localDefault
: globalDefault);
It also works well if null-possible object isn't a variable:
如果可能为 null 的对象不是变量,它也能很好地工作:
string anybody = Parameters["Name"]
?? Settings["Name"]
?? GlobalSetting["Name"];
vs.
对比
string anybody = (Parameters["Name"] != null ? Parameters["Name"]
: (Settings["Name"] != null) ? Settings["Name"]
: GlobalSetting["Name"];
回答by Konrad Rudolph
Is ?? necessary, or should you just use the ternary operator (that most are familiar with)
是 ??必要的,或者你应该只使用三元运算符(大多数人都熟悉)
You should use what best expresses your intent. Since there isa null coalesce operator, use it.
您应该使用最能表达您意图的内容。由于是一个空COALESCE操作,使用它。
On the other hand, since it's so specialized, I don't think it has other uses. I would have preferred an appropriate overload of the ||
operator, as other languages do. This would be more parsimonious in the language design. But well …
另一方面,由于它是如此专业,我认为它没有其他用途。我更喜欢||
运算符的适当重载,就像其他语言一样。这在语言设计中会更加简洁。不过好吧……
回答by Cristian Libardo
I've used it as a lazy load one-liner:
我将它用作延迟加载单行:
public MyClass LazyProp
{
get { return lazyField ?? (lazyField = new MyClass()); }
}
Readable? Decide for yourself.
可读?自己决定。
回答by HanClinto
Cool! Count me as someone who didn't know about the null coalescing operator -- that's pretty nifty stuff.
凉爽的!把我算作一个不知道空合并运算符的人——这是非常漂亮的东西。
I find it much easier to read than the ternary operator.
我发现它比三元运算符更容易阅读。
The first place that comes to mind where I might use it is to keep all of my default parameters in a single place.
我想到的第一个可能使用它的地方是将所有默认参数保存在一个地方。
public void someMethod( object parm2, ArrayList parm3 )
{
someMethod( null, parm2, parm3 );
}
public void someMethod( string parm1, ArrayList parm3 )
{
someMethod( parm1, null, parm3 );
}
public void someMethod( string parm1, object parm2, )
{
someMethod( parm1, parm2, null );
}
public void someMethod( string parm1 )
{
someMethod( parm1, null, null );
}
public void someMethod( object parm2 )
{
someMethod( null, parm2, null );
}
public void someMethod( ArrayList parm3 )
{
someMethod( null, null, parm3 );
}
public void someMethod( string parm1, object parm2, ArrayList parm3 )
{
// Set your default parameters here rather than scattered through the above function overloads
parm1 = parm1 ?? "Default User Name";
parm2 = parm2 ?? GetCurrentUserObj();
parm3 = parm3 ?? DefaultCustomerList;
// Do the rest of the stuff here
}
回答by Jon Skeet
I've found it useful in two "slightly odd" ways:
我发现它以两种“有点奇怪”的方式很有用:
- As an alternative for having an
out
parameter when writingTryParse
routines (i.e. return the null value if parsing fails) - As a "don't know" representation for comparisons
- 作为
out
编写TryParse
例程时具有参数的替代方法(即,如果解析失败则返回空值) - 作为比较的“不知道”表示
The latter needs a little bit more information. Typically when you create a comparison with multiple elements, you need to see whether the first part of the comparison (e.g. age) gives a definitive answer, then the next part (e.g. name) only if the first part didn't help. Using the null coalescing operator means you can write pretty simple comparisons (whether for ordering or equality). For example, using a couple of helper classes in MiscUtil:
后者需要更多信息。通常,当您创建与多个元素的比较时,您需要查看比较的第一部分(例如年龄)是否给出了明确的答案,然后仅当第一部分没有帮助时才查看下一部分(例如姓名)。使用空合并运算符意味着您可以编写非常简单的比较(无论是排序还是相等)。例如,在MiscUtil 中使用几个辅助类:
public int Compare(Person p1, Person p2)
{
return PartialComparer.Compare(p1.Age, p2.Age)
?? PartialComparer.Compare(p1.Name, p2.Name)
?? PartialComparer.Compare(p1.Salary, p2.Salary)
?? 0;
}
Admittedly I now have ProjectionComparer in MiscUtil, along with some extensions, which make this kind of thing even easier - but it's still neat.
诚然,我现在在 MiscUtil 中有 ProjectionComparer 以及一些扩展,这使得这种事情变得更加容易 - 但它仍然很整洁。
The same can be done for checking for reference equality (or nullity) at the start of implementing Equals.
在开始实现 Equals 时检查引用相等(或无效)也可以这样做。
回答by Matt Hamilton
I've used ?? in my implementation of IDataErrorInfo:
我用过??在我的 IDataErrorInfo 实现中:
public string Error
{
get
{
return this["Name"] ?? this["Address"] ?? this["Phone"];
}
}
public string this[string columnName]
{
get { ... }
}
If any individual property is in an "error" state I get that error, otherwise I get null. Works really well.
如果任何单个属性处于“错误”状态,我会收到该错误,否则我会收到空值。效果很好。
回答by Matt Hamilton
Another advantage is that the ternary operator requires a double evaluation or a temporary variable.
另一个优点是三元运算符需要双重评估或临时变量。
Consider this, for instance:
考虑一下,例如:
string result = MyMethod() ?? "default value";
while with the ternary operator you are left with either:
使用三元运算符时,您只剩下以下任一项:
string result = (MyMethod () != null ? MyMethod () : "default value");
which calls MyMethod twice, or:
两次调用 MyMethod ,或者:
string methodResult = MyMethod ();
string result = (methodResult != null ? methodResult : "default value");
Either way, the null coalescing operator is cleaner and, I guess, more efficient.
无论哪种方式,空合并运算符都更干净,我猜也更有效。
回答by Matt Hamilton
Only problem is the null-coalesce operator doesn't detect empty strings.
唯一的问题是空合并运算符不检测空字符串。
i.e.
IE
string result1 = string.empty ?? "dead code!";
string result2 = null ?? "coalesced!";
OUTPUT:
输出:
result1 = "" result2 = coalesced!
result1 = "" result2 = coalesced!
I'm currently looking into overriding the ?? operator to work around this. It sure would be handy to have this built into the Framework.
我目前正在考虑覆盖 ?? 操作员来解决这个问题。将它内置到框架中肯定会很方便。
Thoughts?
想法?
回答by a CVn
Is ?? necessary, or should you just use the ternary operator (that most are familiar with)
是 ??必要的,或者你应该只使用三元运算符(大多数人都熟悉)
Actually, my experience is that all too few people are familiar with the ternary operator (or more correctly, the conditionaloperator; ?:
is "ternary" in the same sense that ||
is binary or +
is either unary or binary; it does however happen to be the only ternary operator in many languages), so at least in that limited sample, your statement fails right there.
实际上,我的经验是,很少有人熟悉三元运算符(或更准确地说,条件运算符;?:
是与||
二元或+
一元或二元相同意义上的“三元” ;然而,它确实是只有许多语言中的三元运算符),所以至少在那个有限的样本中,你的陈述就在那里失败了。
Also, as mentioned before, there is one major situation when the null coalescing operator is very useful, and that is whenever the expression to be evaluated has any side effects at all. In that case, you cannotuse the conditional operator without either (a) introducing a temporary variable, or (b) changing the actual logic of the application. (b) is clearly not appropriate in any circumstances, and while it's a personal preference, I don't like cluttering up the declaration scope with lots of extraneous, even if short-lived, variables, so (a) is out too in that particular scenario.
此外,如前所述,当空合并运算符非常有用时,有一种主要情况,那就是要评估的表达式有任何副作用。在这种情况下,您不能在不 (a) 引入临时变量或 (b) 更改应用程序的实际逻辑的情况下使用条件运算符。(b) 显然在任何情况下都不合适,虽然这是个人偏好,但我不喜欢用大量无关紧要的变量(即使是短暂的)来混淆声明范围,所以 (a) 太出戏了特定场景。
Of course, if you need to do multiple checks on the result, the conditional operator, or a set of if
blocks, are probably the tool for the job. But for simple "if this is null, use that, otherwise use it", the null coalescing operator ??
is perfect.
当然,如果您需要对结果进行多次检查,条件运算符或一组if
块可能是完成这项工作的工具。但是对于简单的“如果这是空的,使用那个,否则使用它”,空合并运算符??
是完美的。
回答by Ryan
The biggest advantage that I find to the ??
operator is that you can easily convert nullable value types to non-nullable types:
我发现??
运算符的最大优点是您可以轻松地将可空值类型转换为不可空类型:
int? test = null;
var result = test ?? 0; // result is int, not int?
I frequently use this in Linq queries:
我经常在 Linq 查询中使用它:
Dictionary<int, int?> PurchaseQuantities;
// PurchaseQuantities populated via ASP .NET MVC form.
var totalPurchased = PurchaseQuantities.Sum(kvp => kvp.Value ?? 0);
// totalPurchased is int, not int?