typeshape-csharp 0.10.0

dotnet add package typeshape-csharp --version 0.10.0                
NuGet\Install-Package typeshape-csharp -Version 0.10.0                
此命令旨在在 Visual Studio 的包管理器控制台中使用,因为它使用 NuGet 模块的 Install-Package 版本。
<PackageReference Include="typeshape-csharp" Version="0.10.0" />                
对于支持 PackageReference 的项目,请将此 XML 节点复制到项目文件中以引用包。
paket add typeshape-csharp --version 0.10.0                
#r "nuget: typeshape-csharp, 0.10.0"                
#r 指令可用于 F# Interactive 和 Polyglot Notebooks。请将此内容复制到交互式工具或脚本的源代码中以引用包。
// Install typeshape-csharp as a Cake Addin
#addin nuget:?package=typeshape-csharp&version=0.10.0

// Install typeshape-csharp as a Cake Tool
#tool nuget:?package=typeshape-csharp&version=0.10.0                

typeshape-csharp

包含 TypeShape 库的示例迁移,适应性改进以适应 C# 中的模式和习惯用法。该库提供了一种类型模型,有助于开发高性能的数据类型通用组件,如序列化器、记录器、转换器和验证器。其编程模型在核心上采用了一种 访问者模式的变体,它允许对任意类型图进行强类型遍历:它可以用于生成不产生分配成本的对象遍历算法。有关额外的指南和 API 文档,请参阅项目网站。

该项目包括两个形状模型提供者:一个 反射衍生的 和一个 源生成的。因此,任何基于形状模型构建的数据类型通用应用程序在目标源生成模型时会自动获得 trim safety/NativeAOT 支持。

使用库

用户可以使用内置的源生成器提取特定类型的形状模型

ITypeShape<MyPoco> shape = TypeShapeProvider.Resolve<MyPoco>();

[GenerateShape] // Auto-generates a static abstract factory for ITypeShape<MyPoco>
public partial record MyPoco(string x, string y);

对于当前编译中不可访问的类型,可以使用单独的见证类型生成实现

ITypeShape<MyPoco[]> shape = TypeShapeProvider.Resolve<MyPoco[], Witness>();
ITypeShape<MyPoco[][]> shape = TypeShapeProvider.Resolve<MyPoco[][], Witness>();

// Generates factories for both ITypeShape<MyPoco[]> and ITypeShape<MyPoco[][]>
[GenerateShape<MyPoco[]>]
[GenerateShape<MyPoco[][]>]
public partial class Witness;

该库还提供了一个基于反射的提供者

using TypeShape.ReflectionProvider;

ITypeShape<MyPoco> shape = ReflectionTypeShapeProvider.Default.GetShape<MyPoco>();
public record MyPoco(string x, string y);

在两种情况下,提供商将为MyPoco生成一个强类型的类型模型。可以将类型的模型输入到使用TypeShape的访问者模式声明的通用消费者。

示例:编写一个类型通用计数器

类型通用编程的最简单的例子是在给定的对象图中计算节点的数量。这可以通过扩展TypeShapeVisitor类来实现

public sealed partial class CounterVisitor : TypeShapeVisitor
{
    // For the sake of simplicity, ignore collection types and just focus on properties/fields.
    public override object? VisitObject<T>(IObjectTypeShape<T> objectShape, object? state)
    {
        // Recursively generate counters for each individual property/field:
        Func<T, int>[] propertyCounters = objectShape.GetProperties()
            .Where(prop => prop.HasGetter)
            .Select(prop => (Func<T, int>)prop.Accept(this)!)
            .ToArray();

        // Compose into a counter for the current type.
        return new Func<T?, int>(value =>
        {
            if (value is null)
                return 0;

            int count = 1; // the current node itself
            foreach (Func<T, int> propertyCounter in propertyCounters)
                count += propertyCounter(value);

            return count;
        });
    }

    public override object? VisitProperty<TDeclaringType, TPropertyType>(IPropertyShape<TDeclaringType, TPropertyType> propertyShape, object? state)
    {
        Getter<TDeclaringType, TPropertyType> getter = propertyShape.GetGetter(); // extract the getter delegate
        var propertyTypeCounter = (Func<TPropertyType, int>)propertyShape.PropertyType.Accept(this)!; // extract the counter for the property type
        return new Func<TDeclaringType, int>(obj => propertyTypeCounter(getter(ref obj))); // compose to a property-specific counter
    }
}

现在我们使用访问者定义一个计数器工厂

public static class Counter
{
    private readonly static CounterVisitor s_visitor = new();

    public static Func<T?, int> CreateCounter<T>() where T : ITypeShapeProvider<T>
    {
        ITypeShape<T> typeShape = T.GetShape();
        return (Func<T?, int>)typeShape.Accept(s_visitor)!;
    }
}

然后我们可以将其应用于我们的POCO的形状,如下所示

Func<MyPoco?, int> pocoCounter = Counter.CreateCounter<MyPoco>();

[GenerateShape]
public partial record MyPoco(string? x, string? y);

本质上,TypeShape使用访问者折叠一个强类型的Func计数器委托,但一旦调用委托,它就不再依赖于访问者:它仅定义了一个强类型委托调用链,构建后调用成本低

pocoCounter(new MyPoco("x", "y")); // 3
pocoCounter(new MyPoco("x", null)); // 2
pocoCounter(new MyPoco(null, null)); // 1
pocoCounter(null); // 0

有关更多详细信息,请参阅项目页面上的README文件

产品 兼容和额外的计算目标框架版本。
.NET net8.0兼容。 net8.0-android已计算。 net8.0-browser已计算。 net8.0-ios已计算。 net8.0-maccatalyst已计算。 net8.0-macos已计算。 net8.0-tvos已计算。 net8.0-windows已计算。
兼容的目标框架
包含的目标框架(在包中)
了解更多关于目标框架.NET Standard的信息。
  • net8.0

    • 无依赖项。

NuGet包

该包未由任何NuGet包使用。

GitHub仓库

该包未由任何流行的GitHub仓库使用。

版本 下载 最后更新
0.10.0 79 5/31/2024
0.9.2 97 5/19/2024
0.9.1 79 5/15/2024
0.9.0 71 5/13/2024
0.8.0 109 4/20/2024
0.7.1 98 4/4/2024
0.7.0 73 4/4/2024
0.6.1 88 2/1/2024
0.6.0 105 1/16/2024
0.5.2 118 12/12/2023
0.5.1 108 12/7/2023
0.5.0 111 12/7/2023
0.4.0 126 11/13/2023
0.3.3 115 11/4/2023
0.3.2 128 10/21/2023
0.3.1 123 10/7/2023
0.3.0 97 9/25/2023
0.2.1 121 9/23/2023
0.2.0 116 9/22/2023
0.1.3 104 9/18/2023
0.1.2 109 9/18/2023
0.1.1 106 9/17/2023
0.1.0 93 9/17/2023