C# 12 中的 Primary Constructor
The following article is from amazingdotnet Author WeihanLi
Intro
在即将到来的 C# 12 中,觉得 Primary Constructor 算是比较实用的特性之一了,和大家分享一下
Sample
直接来看几个使用示例吧
file class Animal(string name)
{
public string Name => name;
}
file sealed class Cat(string Name) : Animal(Name){}
file struct Point(int x, int y)
{
public int X => x;
public int Y => y;
}
可以用于class
也可以用于 struct
,相当于一个字段,可以直接在类型中直接引用类似的,对于构造函数依赖注入,我们也可以使用这个特性来进行简化,就不需要再手动声明字段了,示例如下:
file sealed class CrudHelper<T>(IIdGenerator idGenerator)
{
public CrudHelper(): this(GuidIdGenerator.Instance)
{
}
public string Create(T t)
{
// Biu...
return idGenerator.NewId();
}
}
What's inside
那么它实际是如何工作的呢,我们反编译看下前面的 CrudHelper
, 反编译结果如下:
internal sealed class <PrimaryConstructorSample>FB47A7FDD6A2F32139FF8A728FBC1FE107CACFA93EA6284446EA366B2274F584F__CrudHelper<T>
{
[CompilerGenerated]
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private IIdGenerator<idGenerator> P;
public <PrimaryConstructorSample>FB47A7FDD6A2F32139FF8A728FBC1FE107CACFA93EA6284446EA366B2274F584F__CrudHelper(IIdGenerator idGenerator)
{
< idGenerator > P = idGenerator;
base..ctor();
}
public <PrimaryConstructorSample>FB47A7FDD6A2F32139FF8A728FBC1FE107CACFA93EA6284446EA366B2274F584F__CrudHelper()
: this((IIdGenerator)GuidIdGenerator.Instance)
{
}
public string Create(T t)
{
return < idGenerator > P.NewId();
}
}
从反编译结果可以看出来,实际就是生成了一个私有的字段,并且在构造方法里进行了赋值,而且字段上增加了 DebuggerBrowsable(DebuggerBrowsableState.Never) Attribute仔细看的话会发现字段不是 readonly 的,关于这一点,第一眼觉得,是不是可以声明称 readonly 的字段,目前来说字段是可以被修改的,不是 readonly 的,而且大概率以后也会保持这样,这样有着更大的灵活性,以后如果允许指定 access level(public/protected/..) 也不需要再变更这个字段,详细可以参考这个讨论:https://github.com/dotnet/csharplang/discussions/7377所以下面的示例也是可以编译通过的
file sealed class Dog(string name, int age) : Animal(name)
{
public int Age => age;
public void OneYearPassed()
{
age++;
System.Console.WriteLine("One year passed, now age is: {0}", age);
}
}
var dog = new Dog("Spike", 3);
Console.WriteLine(dog.Age);
dog.OneYearPassed();
输出结果如下:
3One year passed, now age is: 4
More
需要注意,非 record 类型的 primary constructor 和 record 类型的 primary constructor 并不相同,差别较大,对于 record 类型来说会生成属性而不是字段,这一点区别很大,而且目前来说字段是私有的,不能被外部类型直接引用,其次 record 类型会生成 deconstructor 和自定义的相等性比较等简而言之,非 record 类型的 primary constructor 更简单一些,只有一个字段更多
- EOF -
.NET 开源免费功能最全的商城项目深入理解C#泛型:new与where关键字全解析
看完本文有收获?请转发分享给更多人
推荐关注「DotNet」,提升.Net技能
点赞和在看就是最大的支持❤️