shi*_*ngo 82 c# syntax function method-signature c#-11.0
来自https://source.dot.net/#System.Private.CoreLib/Hashtable.cs,475:
public virtual bool ContainsKey(object key!!)
Run Code Online (Sandbox Code Playgroud)
它看起来像两个 null-forgiving 运算符。有相关文件吗?
can*_*on7 113
这是一个空参数检查语法,将在 C# 11 中引入。根据社区反馈,该提案已被回滚。
语法:
public void Foo(string bar!!)
{
}
Run Code Online (Sandbox Code Playgroud)
大致相当于:
public void Foo(string bar)
{
if (bar is null)
{
throw new ArgumentNullException(nameof(bar));
}
}
Run Code Online (Sandbox Code Playgroud)
...虽然实际的实现使用了一个 throw helper,比如:
public void Foo(string bar)
{
<PrivateImplementationDetails>.ThrowIfNull(bar, "bar");
}
[CompilerGenerated]
internal sealed class <PrivateImplementationDetails>
{
internal static void Throw(string paramName)
{
throw new ArgumentNullException(paramName);
}
internal static void ThrowIfNull(object argument, string paramName)
{
if (argument == null)
{
Throw(paramName);
}
}
}
Run Code Online (Sandbox Code Playgroud)
包含语句的方法throw不太可能被 JIT 内联,因此使用 throw 帮助器使您的方法更有可能被内联,这可能会完全删除空检查!请参阅 SharpLab。
请注意,使用!!是方法的实现细节:它只会导致编译器插入您本来可以自己编写的代码。这意味着从throw到!!(或反之亦然)并不是重大变化。
然而,有几个地方!!会让编译器生成您无法(轻松)手工编写的代码。
特别有用的一个地方!!是具有主构造函数的记录。例如:
public record Person(string Name!!, int Age);
Run Code Online (Sandbox Code Playgroud)
为了正确地对Name以前版本的 C# 中的参数进行空检查,您必须手写如下:
public record Person
{
public string Name { get; init; }
public int Age { get; init; }
public Person(string name, int age)
{
if (name is null)
throw new ArgumentNullException(nameof(name));
(Name, Age) = (name, age);
}
public void Deconstruct(out string name, out int age) =>
(name, age) = (Name, Age);
}
Run Code Online (Sandbox Code Playgroud)
!!另一个你无法自己编写的东西的地方是在链式构造函数调用中:
public class C
{
public C(int i) { }
public C(string s!!) : this(s.Length) { }
}
Run Code Online (Sandbox Code Playgroud)
s在访问之前会进行空检查s.Length,如下所示(这不是有效的 C#):
public C(string s)
{
if (s is null)
throw new ArgumentNullException(nameof(s));
C(s.Length);
}
Run Code Online (Sandbox Code Playgroud)
另一个有趣的方面是,空检查是在构造函数中的字段赋值之前插入的。例如:
public class C
{
private readonly ExpensiveObject e = new ExpensiveObject();
public C(string s!!) { }
}
Run Code Online (Sandbox Code Playgroud)
编译为:
public class C
{
private readonly ExpensiveObject e;
public C(string s)
{
if (s is null)
throw new ArgumentNullException(nameof(s));
e = new ExpensiveObject();
}
}
Run Code Online (Sandbox Code Playgroud)
也就是说,空检查发生在 的实例化之前ExpensiveObject。请参阅 SharpLab。
According to the latest updates published by microsoft about c# 11, this feature seems to have been removed.
\n\n\n\nWe previewed parameter null-checking as early as possible because we\nanticipated feedback. This feature allows !! on the end of a parameter\nname to provide parameter null checking before the method begins\nexecution. We included this feature early in C# 11 to maximize\nfeedback, which we gathered from GitHub comments, MVPs, social media,\na conference audience, individual conversations with users, and the C#\ndesign team\xe2\x80\x99s ongoing reflection. We received a wide range of feedback\non this feature, and we appreciate all of it.
\nThe feedback and the wide range of insight we gained from this\nfeedback led us to reconsider this as a C# 11 feature. We do not have\nsufficient confidence that this is the right feature design for C# and\nare removing it from C# 11. We may return to this area again at a\nlater date.
\n
| 归档时间: |
|
| 查看次数: |
9610 次 |
| 最近记录: |