C13RefStructInterfaces

程序员有二十年 2024-09-24 10:40:46
C# 13 Ref Struct InterfacesIntro

C# 从 7.2 开始引入了 ref struct,ref struct 只能分配在栈上,不能被装箱,因为不能被装箱之前的版本中 ref struct 是不能实现接口的,在转成接口的时候会导致发生装箱,这是不被允许的,而我们在做一些设计的时候往往会使用到接口,用接口定义契约 contract,C# 13 开始我们可以允许 ref struct 实现接口,并且增加了可以作为泛型类型约束允许 ref struct 类型

Sample

来看一个简单的示例:

file interface IAge{public int GetAge();}file ref struct Age : IAge{public int GetAge() => 1;}

使用的地方需要这样用:

private static void PrintAge<TAge>(TAge age)where TAge : IAge, allows ref struct{ Console.WriteLine(age.GetAge());}

方法需要声明为泛型参数,并且要指定泛型约束 allows ref struct

我们不能直接声明参数为对应的接口类型,如 IAge,这会导致 ref struct 被装箱,编译器会报错,例如我们这样定义,调用的时候编译器就会报错,这也意味着 ref struct 不能使用接口默认实现方法,因为接口默认实现方法需要转成接口才能使用,而转接口就意味着要发生装箱,对于 ref struct 来说是不被允许的

CS1503: Argument 1: cannot convert from 'CSharp13Samples.RefStructAge' to 'CSharp13Samples.IAge'

private static void PrintAge0(IAge age){ Console.WriteLine(age.GetAge());}

CS1503 error

另外需要显式声明 allows ref struct 默认是不允许将 ref struct 用作泛型类型参数的,不声明也会导致编译器报错

CS9244: The type 'RefStructAge' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'TAge' in the generic type or method 'RefStructInterfaceSample.PrintAge(TAge)'

CS9244-error

除了方法我们也可以声明 Property

internal interface IAge{int AgeNum { get; }int GetAge();}internal ref struct RefStructAge : IAge{public int AgeNum => 1;public int GetAge() => AgeNum;}

如果接口里有定义默认实现方法,在定义 ref struct 的时候就会报错

Interface default implemented methodMore

这一特性可以有助于避免 struct 被装箱导致性能问题,可以更好地利用 ref struct 带来的性能改进和编译器的约束检查

可以实现接口也有有助于在设计前面更加专注在更核心的接口设计上无需关心实现方式,实现的时候选择基于 实现也可以基于 ref struct 来实现, dotnet runtime 的一些 library 里的泛型参数也新增支持了这一特性,例如:https://github.com/dotnet/runtime/issues/102671

library-ref-struct

后续的 runtime library 应该也会基于这一特性优化一些原来基于 的实现,转而使用基于 ref struct 的实现来优化性能

对前面的示例做一个简单的 benchmark

Referenceshttps://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-version-history#c-version-72https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/ref-structhttps://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/structs#1623-ref-modifierhttps://github.com/dotnet/csharplang/blob/main/proposals/csharp-13.0/ref-struct-interfaces.mdhttps://github.com/dotnet/csharplang/issues/7608https://github.com/WeihanLi/SamplesInPractice/blob/main/net9sample/CSharp13Samples/RefStructInterfaceSample.cshttps://github.com/dotnet/runtime/issues/102671https://github.com/dotnet/runtime/issues/105276

0 阅读:0

程序员有二十年

简介:感谢大家的关注