如何在 .NET Standard 2.0 的 F# 中定义 ref 结构?
How to define a ref struct in F# in .NET Standard 2.0?
当F# 4.5 was announced时,表示:
The F# feature set is comprised of
[...]
The ability to produce IsByRefLike structs (examples of such structs: Span<'T>and ReadOnlySpan<'T>).
如何“生产”这些类型?我尝试了 [<IsByRefLike>]
属性,但在 .NET Standard 2.0 中找不到。
在 System.Runtime.CompilerServices
中找到该属性
open System.Runtime.CompilerServices
[<Struct; IsByRefLike>]
type Apa =
{ A: Span<int>
B: int }
Phillip Carter 在 What's new in F# 4.5(约 21 分钟)中谈到了这一点。
它适用于 .NET Core 和 .NET Framework,但不适用于 .NET Standard 2.0。
从技术上讲,这不是答案。
首先,根据规范,IsByRefLike
是给编译器使用的,不是给开发者使用的:https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.isbyreflikeattribute?view=netframework-4.7.2
其次,当我们确实想从编译器中得到一些东西时,了解我们想从中得到什么是至关重要的。所以一个正确的问题可能是:我需要 ABC 因为我需要做 XYZ,其中 ABC
与 IsByRefLike
相关,然后 XYZ
将是基于 IsByRefLike
的东西。这个问题没有解释为什么需要 IsByRefLike
。
我认为在考虑使用/不使用哪些语言特性时,应该始终权衡极简主义方法:我们真的需要某些特定的语言特性来完成我们的需求吗?想到 F# Option.bind
:如果函数是单行函数,那么 Option.bind
就很棒。但是,如果有一些关于如何解析结果的树,那么最好在不使用 Option.bind
的情况下显式地进行解析。
所以问题是:
- 你真的需要
IsByRefLike
吗?
- 如果您认为自己可以,请 post 举例说明您实际 需要它的地方。
从 .NET SDK 6.0.200(在 Visual Studio 2022 17.1 中可用)开始,F# 编译器可识别 user-defined IsByRefLikeAttribute
。以下代码将透明地启用在 .NET Standard 2.0 以及更高版本的框架上定义 ref 结构:
#if NETSTANDARD2_0
namespace System.Runtime.CompilerServices
open System
[<Sealed; AttributeUsage(AttributeTargets.Struct)>]
type IsByrefLikeAttribute() = inherit Attribute()
#endif
namespace MyLibrary
open System
open System.Runtime.CompilerServices
[<IsByRefLike>]
type MyRefStruct(span: Span<int>) = struct end
当F# 4.5 was announced时,表示:
The F# feature set is comprised of
[...]
The ability to produce IsByRefLike structs (examples of such structs: Span<'T>and ReadOnlySpan<'T>).
如何“生产”这些类型?我尝试了 [<IsByRefLike>]
属性,但在 .NET Standard 2.0 中找不到。
在 System.Runtime.CompilerServices
open System.Runtime.CompilerServices
[<Struct; IsByRefLike>]
type Apa =
{ A: Span<int>
B: int }
Phillip Carter 在 What's new in F# 4.5(约 21 分钟)中谈到了这一点。
它适用于 .NET Core 和 .NET Framework,但不适用于 .NET Standard 2.0。
从技术上讲,这不是答案。
首先,根据规范,IsByRefLike
是给编译器使用的,不是给开发者使用的:https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.isbyreflikeattribute?view=netframework-4.7.2
其次,当我们确实想从编译器中得到一些东西时,了解我们想从中得到什么是至关重要的。所以一个正确的问题可能是:我需要 ABC 因为我需要做 XYZ,其中 ABC
与 IsByRefLike
相关,然后 XYZ
将是基于 IsByRefLike
的东西。这个问题没有解释为什么需要 IsByRefLike
。
我认为在考虑使用/不使用哪些语言特性时,应该始终权衡极简主义方法:我们真的需要某些特定的语言特性来完成我们的需求吗?想到 F# Option.bind
:如果函数是单行函数,那么 Option.bind
就很棒。但是,如果有一些关于如何解析结果的树,那么最好在不使用 Option.bind
的情况下显式地进行解析。
所以问题是:
- 你真的需要
IsByRefLike
吗? - 如果您认为自己可以,请 post 举例说明您实际 需要它的地方。
从 .NET SDK 6.0.200(在 Visual Studio 2022 17.1 中可用)开始,F# 编译器可识别 user-defined IsByRefLikeAttribute
。以下代码将透明地启用在 .NET Standard 2.0 以及更高版本的框架上定义 ref 结构:
#if NETSTANDARD2_0
namespace System.Runtime.CompilerServices
open System
[<Sealed; AttributeUsage(AttributeTargets.Struct)>]
type IsByrefLikeAttribute() = inherit Attribute()
#endif
namespace MyLibrary
open System
open System.Runtime.CompilerServices
[<IsByRefLike>]
type MyRefStruct(span: Span<int>) = struct end