是否有参数的合并运算符?

Ian*_*ton 0 c#

如果F“在”上a,我可以这样做...

var obj = a?.F();
Run Code Online (Sandbox Code Playgroud)

如果F未开启a,则必须执行此操作...

var obj = a == null ? null : MyFunc.F((A) a);
Run Code Online (Sandbox Code Playgroud)

还是我 如果参数值为null,是否有更简洁的方法跳过方法调用?

Eri*_*ert 8

简短的答案是没有,没有简洁的方法可以做到这一点。

稍长的答案仍然是否,但是这里有一个有趣的语言设计要点。如果我自己说的话,C#是由品味极高的人设计的,但是它是经过很长时间设计的。就其对无效性的处理而言,这是最明显的。

在C#1.0中,我们采用了C,C ++,Java,JavaScript等传统语言,其中包含引用和值,并且引用可以为null。这有好处;如果没有的话,托尼爵士根本就不会发明空引用。但这有缺点:我们可能会使用null引用,将null取消引用会导致程序崩溃,并且引用和值类型之间存在不一致的地方:引用类型具有自然的“无值”值,而值类型则没有。

In C# 2.0 we added nullable value types, but nullable value types do not behave like nullable reference types. Of course nullable values types are not references, so you cannot "dereference" them, but if we squint a little, the .Value property looks a lot like "dereferencing", and it leads to a similar crash if the value is null. In that sense, they behave the same, but in other senses, they do not. Adding together two nullable integers does not crash if one of them is null; instead, the result is also null.

So at this point we have a contradiction built into the language:

Using a null value of a nullable value type usually automatically propagates the null, but using a null reference can crash.

And of course C# has then gone on to add a variety of features that make null references behave more like null values, like ?. and the related operations. There are also proposals for C# 8 that are very exciting, and will support "non nullable reference type" scenarios.

But the bolded text above is the fundamental problem you've pinpointed: the semantics of operators on nullable reference types are almost always "lift the non-nullable version of the operator to nullable types; if all the operands are non-null then the result is the same as the unlifted version; otherwise, the result is null". However, those semantics are not automatically extended to the . member access operator or the () call operator, regardless of whether the operands are nullable value types or nullable reference types. . can be lifted explicitly by ?. but the () operator does not get lifted to nullable semantics, ever.

Imagine a language like C# 1.0, but with Nullable<T> built in from the start, such that it applied to both reference and value types. In that world, you can see natural ways to implement generalized lifting, where if you have a method

class C { string M(double, int[]) }
Run Code Online (Sandbox Code Playgroud)

and you call it with a Nullable<C> receiver, or Nullable<double> and Nullable<int[]> arguments, you automatically get the code that we build for you for nullable integer arithmetic: check whether the receiver or any arguments are null, and if they are, result in a null Nullable<string>. Otherwise, call the function normally and use the non-nullable result.

The C# compiler already implements these semantics for all user-defined operators declared on struct types; it would not be hardly any difficulty at all to extend those semantics to other kinds of methods. But we can't do it now; there are far too many backwards-compatibility issues to solve.

This design choice would also have the nice property that it would be a correct implementation of the "maybe monad".

But that's not the world we are in, and it's largely because these design considerations evolved over time, rather than being invented all at once. The next time you invent a new language, consider carefully how to represent nullability!