的C#9的记录功能规范包括以下内容:
一个记录类型包含两个复制成员:
采用记录类型的单个参数的构造函数。它被称为“复制构造函数”。具有编译器保留名称的合成公共无参数实例“克隆”方法
但我似乎无法调用这两个复制成员中的任何一个:
public record R(int A);
// ...
var r2 = new R(r); // ERROR: inaccessible due to protection level
var r3 = r.Clone(); // ERROR: R does not contain a definition for Clone
Run Code Online (Sandbox Code Playgroud)
由此,我了解到构造函数是受保护的,因此无法在记录的继承层次结构之外访问。所以我们只剩下这样的代码:
var r4 = r with { };
Run Code Online (Sandbox Code Playgroud)
但是克隆呢?根据上述规范,克隆方法是公开的。但它的名字是什么?或者它是一个有效的随机字符串,因此不应在记录的继承层次结构之外调用它?如果是这样,深复制记录的正确方法是什么?从规范看来,人们可以创建自己的克隆方法。是这样吗,它应该如何工作的一个例子是什么?
Azure Service Fabric似乎专注于所有数据都适合RAM并且持久性用作后备存储的场景.可靠服务旨在将信息存储在可靠集合中,该集合使用日志检查点系统将记录的信息写入RAM.同时,对于Reliable Actors,默认的actor状态提供者是"Service Fabric平台提供的分布式Key-Value存储".这似乎表明同样的限制将适用.
然而,可能存在这样的情况:人们想要将Service Fabric用于"热数据",而是将"冷数据"写入某种形式的永久存储器.处理此转换的最佳做法是什么?
在Orleans中,这似乎是使用Azure表等持久性存储自动处理的.但似乎Service Fabric和Reliable Collections的主要设计目的是避免需要外部服务,从而增强数据局部性.当前的文档预计可能会有人希望将数据移动到某个永久存储库以进行灾难恢复和分析,但它没有讨论在持久性支持的内存中的actor和更永久的存储形式之间来回移动数据的可能性.
一个可能的答案是Service Fabric已经这样做了.也许可靠字典有一些内置机制,用于在持久性支持的内存存储和永久存储之间进行切换.
或者,也许答案是必须管理自己.一种方法可能是让Actor跟踪它的"热"程度并根据需要切换其持久性存储.但这牺牲了Actor模型的一个好处,即演员的自动分配和释放.同样,我们可能会定期从Reliable Dictionary中删除项目并将其添加到其他持久性存储中,然后将其添加回来.但是,这又要求了解何时进行转换是有意义的.
一些例子可能有助于明确这一点:
(1)假设我们正在实施一个有许多不同"房间"的多人游戏.我们不需要同时在内存中的所有房间,但我们需要将它们移动到内存中,并在玩家加入后使用本地持久性作为备份.
(2)假设我们正在实现一个仅附加的B树作为数据库的一部分.诱惑是让每个B-Tree节点成为有状态的角色.我们希望热b树保留在内存中,但当然整个索引不能在内存中.看来这是一个已经为DocumentDB这样的东西实现的核心场景,但是从文档中我不清楚如何做到这一点.
我找到的一个相关问题就在这里.但是,该问题主要关注何时使用Azure Service Fabric与外部服务.我的问题是是否需要在它们之间进行转换,或者Azure Service Fabric是否已具备此处所需的所有功能.
创建一个针对.Net Standard 2.0的Roslyn分析器包后,当我在另一个项目中引用该包时,收到以下错误:
'C:\ Users\username.nuget\packages\analyzer4\1.0.0.1\analyzers\dotnet\cs\Analyzer4.dll'取决于'netstandard,Version = 2.0.0.0,Culture = neutral,PublicKeyToken = cc7b13ffcd2ddd51'但它是未找到.除非将缺少的组件添加为分析器参考,否则分析仪可能无法正确运行.
使用分析仪的项目的重新制作就在这里.这个repro是一个vanilla .Net Core 2.0控制台应用程序,引用了分析器,没有任何其他代码.分析器本身只是通过在Visual Studio中创建默认的Analyzer项目来构建,更改它以使其以netstandard2.0而不是netstandard1.3为目标,然后在发布模式下构建以生成.nupkg文件.正如repro演示的那样,分析仪可以正常工作,但会生成警告.
在Github上的各个地方都讨论过这个警告,例如这里,但在这些情况下,分析器作者故意剥离了一些本地库代码.在这种情况下,分析器不会引用任何其他库.
我不清楚将分析器添加为"分析器参考"的确切含义,而不仅仅是常规项目参考.我确实尝试过改变
<PackageReference Include="Analyzer4" Version="1.0.0.1" />
Run Code Online (Sandbox Code Playgroud)
至
<Analyzer Include="..\LocalPackages\Analyzer4.1.0.0.1.nupkg" />
Run Code Online (Sandbox Code Playgroud)
但这导致了另一条错误消息(" PE图像不包含托管元数据 ").
任何人都可以解释这个错误意味着什么,理想情况下如何解决它?
我正在编写一个源代码生成器,需要知道我使用 Microsoft.CodeAnalysis 向其添加功能的类是否是记录。
我可以通过切换到语法模型来做到这一点,如下所示:
public static bool IsRecord(this ITypeSymbol type)
{
if (type == null || type.TypeKind != TypeKind.Class)
return false;
bool isRecord = (type.DeclaringSyntaxReferences.Any(x => (x.SyntaxTree.GetRoot().FindNode(x.Span) is RecordDeclarationSyntax)));
return isRecord;
}
Run Code Online (Sandbox Code Playgroud)
但是有没有办法用语义模型来做到这一点?我很可能遗漏了一些明显的东西,但我已经检查了在我看来是明显的地方,并且我还在 github 上进行了搜索。Roslyn内部似乎有一个IsRecord,但我找不到任何公开的内容。如果我无法在语义模型中访问它,即使该类型来自从另一个程序集导入的代码,上述内容是否也能正常工作?
如何将返回 Span 的方法作为参数传递?
using System.Memory;
public Span<byte> CallSpanFactory1(Func<Span<byte>> spanFactory)
{
return spanFactory();
}
Run Code Online (Sandbox Code Playgroud)
此代码返回错误“类型‘Span’不能用作类型参数”(这是有道理的,因为使用 ref 结构作为泛型类型参数可能会导致装箱,因此被禁止)。