在主要性能和易用性或清晰度等方面,以下两种等效方式对于零条件运算符最佳?
这个:
idString = child?.Id;
fatherName = child?.Father?.Name;
motherName = child?.Mother?.Name;
Run Code Online (Sandbox Code Playgroud)
或者(假设所有本地变量都已为空)这:
if (child != null)
{
idString = child.Id;
fatherName = child.Father?.Name;
motherName = child.Mother?.Name;
}
Run Code Online (Sandbox Code Playgroud)
性能甚至是一个问题吗?
观察:如果text为null,则此方法返回True.我期待False.
return text?.IndexOf('A') != -1;
Run Code Online (Sandbox Code Playgroud)
当我使用ILSpy(或检查IL)反映上述行时,这是生成的代码:
return text == null || text.IndexOf('A') != -1;
Run Code Online (Sandbox Code Playgroud)
这是我真正需要满足我的期望:
return text != null && text.IndexOf('A') != -1;
Run Code Online (Sandbox Code Playgroud)
问题:有人对Null条件代码生成OR表达式的原因有一个很好的解释吗?
我一直在寻找在调用方法(或方法链)时处理空对象的最佳选择.
我们的常见做法是检查条件:
if ( customObject != null ) {
customObject.callMe();
}
Run Code Online (Sandbox Code Playgroud)
使用扩展方法可以进一步改进:
Program customObject = null;
if (customObject.NotNull()) {
customObject.CallMe();
}
public static bool NotNull(this object o) {
return o == null;
}
Run Code Online (Sandbox Code Playgroud)
请注意:我通常会忽略!从我的编程实践.因此,明智地说对我来说扩展方法很好.
但是,在处理涉及Method链的时候,它变得非常复杂.
customObject.CallMe().CallMe2() ex...
Run Code Online (Sandbox Code Playgroud)
你怎么认为它可以在C#中处理,所以CallMe只有在customObject不为null时CallMe2调用它,并且仅在CallMe返回非null对象时才被调用.
当然我可以使用If条件或三元运算符.但是,我想知道vNext,C#5.0是否有一些东西可以提供.
elvis运算符,即null条件运算符,非常酷.
在LINQ查询中,它与null合并"??"一致很好用 运营商.
Somedata.Where(dt=>(dt?.Inner?.InnerMost?.Include=="Yes")??false);
Run Code Online (Sandbox Code Playgroud)
但是如果你需要施放中间值,你会怎么做?
对于链中的一个链接,它可以正常工作.
Somedata.Where(dt=>(
((InnerClass)dt?.Inner)
?.InnerMost)?.Include=="Yes")
??false);
Run Code Online (Sandbox Code Playgroud)
但是通过额外的必要施法,施法和调用被"驱散".
Somedata.Where(dt=>(
((InnerMostClass) <=== Cast
((InnerClass)dt?.Inner)
?.InnerMost)?.Include=="Yes")) <=== Use
??false);
Run Code Online (Sandbox Code Playgroud)
可能在这里不止一次弄乱了括号,但我希望你明白这个想法.
虽然这个"火车残骸"调用链是一种代码味道,但这样做是否有更具表现力的方式来提高简洁性和清晰度?
c# linq null-coalescing-operator c#-6.0 null-conditional-operator
我有以下代码行:
user.Exists = await this.repository?.Exists(id);
Run Code Online (Sandbox Code Playgroud)
Exists在左侧是User班级的财产.它的类型只是bool,而不是bool?.Exists右侧的方法是一种API方法,用于检查存储库中是否存在给定实体.它回来了Task<bool>.我想先检查存储库是否为null,因此我使用null条件运算符.我认为如果存储库为null,那么整个右侧只返回null,这不能分配给一个bool类型,但编译器似乎没问题.是否只是以某种方式默认为错误值?
这是一个编译器错误还是有一个特定的选择原因,为什么空条件运算符不适Func用于泛型方法?
举个例子,下面的代码不能编译
public static T Test<T>(Func<T> func)
{
return func?.Invoke() ?? default(T);
}
Run Code Online (Sandbox Code Playgroud)
编译器产生的错误是 CS0023 Operator '?' cannot be applied to operand of type 'T'
我知道你可以做到这一点但是:
public static T Test<T>(Func<T> func)
{
return func != null ? func() : default(T);
}
Run Code Online (Sandbox Code Playgroud)
那为什么不允许这样呢?
Action<T>然而,进一步详细说明可以按预期工作.
public static void Test<T>(Action<T> action, T arg)
{
action?.Invoke(arg);
}
Run Code Online (Sandbox Code Playgroud)
更新(2017-01-17):
经过一些更多的研究,即使有以下几点,它也没有多大意义:
假设我们有一个类(参考类型)
public class Foo
{
public int Bar { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
让我们说我们有一个 Func<int>
Func<int> fun = () => 10;
Run Code Online (Sandbox Code Playgroud)
以下作品: …
该代码为何起作用:
if (list?.Any() == true)
Run Code Online (Sandbox Code Playgroud)
但是这段代码没有:
if (list?.Any())
Run Code Online (Sandbox Code Playgroud)
说错误CS0266无法隐式转换类型“布尔”?“布尔”
那么,为什么不是语言功能在if语句中进行这种隐式转换呢?
当方法属于所讨论的对象时,空条件运算符非常有用,但是如果所讨论的对象是参数怎么办?例如,这个可以缩短吗?
var someList = new List<SomeType>();
if (anotherList.Find(somePredicate) != null)
{
someList.Add(anotherList.Find(somePredicate))
}
Run Code Online (Sandbox Code Playgroud)
我想到的一个解决方案是使用如下扩展方法:
public static void AddTo<T>(this T item, List<T> list)
{
list.Add(item);
}
Run Code Online (Sandbox Code Playgroud)
这样,第一个代码块可以减少为:
var someList = new List<SomeType>();
anotherList.Find(somePredicate)?.AddTo(someList);
Run Code Online (Sandbox Code Playgroud)
但此解决方案特定于本示例(即,如果对象不为空,则将对象添加到列表中)。是否有通用方法来指示如果参数为 null,则不应运行该方法?
我很困惑null条件运算符如何与普通属性访问级联.拿这两个例子:
a?.b.c
(a?.b).c
Run Code Online (Sandbox Code Playgroud)
我希望它们是等价的:首先,a?.b评估值,然后result.c进行评估.因此,如果a == null应该抛出异常.
但是,这只发生在第二个表达式中.第一个表达式求值为null,意思是它相同a?.b?.c.为什么?
C#和其他语言通常有空条件?.
A?.B?.Do($C);
Run Code Online (Sandbox Code Playgroud)
当 A 或 B 为空时不会出错。我如何在 powershell 中实现类似的功能,有什么更好的方法可以做到:
if ($A) {
if ($B) {
$A.B.Do($C);
}
}
Run Code Online (Sandbox Code Playgroud)