C# 13 Preview 的 field keyword
Intro
C# 13 将以预览版的特性推出 field keyword 特性,等了几年的功能终于要能用上了,目前在最新版本的 VS 预览版本(17.12.0 Preview 3)中已经可用,不过可惜的是 .NET 9 RC 2 SDK 还不支持,得等到 .NET 9 正式版本了
Sample
field
keyword 特性是指在属性(Property)的上下文中支持使用 field
关键词来引用属性背后的字段
我们来看下自动属性的示例:
public string Name { get; set; }
这等同于
private string _name;
public string Name
{
get => _name;
set => _name = value;
}
使用 field
关键词改一下如下:
public string Name
{
get => field;
set => field = value;
}
再来看一个实际一点使用示例:
internal static class FieldKeywordSample
{
public static string Name
{
get;
set => field = value?.Trim() ?? string.Empty;
} = string.Empty;
}
这个示例我们每次对 setter
做了一个 Trim()
的操作,并且保证不给 field 设置 null
, null
时设置为 string.Empty
这在之前版本我们就得先声明成下面这样:
internal static class FieldKeywordSample
{
private static string _name;
public static string Name
{
get => _name;
set => _name = value?.Trim() ?? string.Empty;
} = string.Empty;
}
需要声明这个字段并且 getter
也需要写完整,即使没有特殊逻辑直接返回了字段
使用 field
关键词之后就无需声明字段了,并且如果是直接返回或者设置 value 就可以使用自动属性的写法,如下:
public int Num { get => field > 0 ? field : 0; set; }
public int Num2 { get; set => field = value > 0 ? value : 0; }
所以之前这个功能也被称为半自动属性,public string Name { get; set; }
则是完全自动属性
除了这样 getter
/setter
直接使用,我们也可以在 getter
返回之前、setter
set 之前以及之后做一些自定义的操作,如下:
internal static class FieldKeywordSample
{
public static string Name
{
get;
set => field = value?.Trim() ?? string.Empty;
//set;
} = string.Empty;
public static string Description
{
get => field ?? string.Empty;
set
{
Console.Write(">>>");
Console.WriteLine(field);
Console.WriteLine($"Before set description, {nameof(value)}: {value}");
field = value?.Trim()!;
// CS0103: The name 'field' does not exist in the current context
// Console.WriteLine($"After set description, {field}");
Console.WriteLine("After set description");
Console.Write(">>>");
Console.WriteLine(field);
}
} = default!;
public static void Run()
{
Name = " Hello ";
Console.WriteLine(Name);
Console.WriteLine(Name.Length);
Console.WriteLine(Description is not null);
Description = " World ";
Console.WriteLine(Description);
Console.WriteLine(Description.Length);
}
}
输出结果如下:
More
需要注意,想要体验这个特性的话需要将 LangVersion
设置为 preview
才可以。
注意前面的代码的话会看到注释里有一个 error,当在插值字符串中使用 field
关键词的时候会报错
已经有 PR 在修这个问题了 https://github.com/dotnet/roslyn/pull/75566
dotnet-exec
的预览版本中也支持了这一特性,从这个特性合并到 main 分支开始就在等待发布新的 Roslyn nuget 包
但是一直没有更新,所以后面使用了 Roslyn 的 daily build 版本,额外添加了一个 nuget source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json,感兴趣的话可以看看 nuget.config
https://github.com/WeihanLi/dotnet-exec/blob/main/nuget.config
使用下面这个命令来安装 dotnet-exec
tool 来体验,因为还是预览版特性,需要使用 --preview option 来使用这个特性
dotnet tool update -g dotnet-execute --prerelease
References
https://github.com/dotnet/csharplang/blob/main/proposals/field-keyword.md https://github.com/dotnet/csharplang/issues/140 https://github.com/dotnet/roslyn/pull/75566 https://github.com/WeihanLi/SamplesInPractice/blob/main/net9sample/CSharp13Samples/FieldKeywordSample.cs https://github.com/WeihanLi/dotnet-exec/blob/main/nuget.config
点击下方卡片关注DotNet NB
一起交流学习
▲ 点击上方卡片关注DotNet NB,一起交流学习
请在公众号后台