• Natasha 4.0 探索之路系列(四) 模板 API


    Natasha 模板

    Natasha 在编译单元的基础上进行了封装整理, 并提供了多种模板帮助开发者构建功能.
    使用此篇的 API 前提是您对 C# 非常熟悉, 对系统的一些类型足够了解.
    据此 Natasha 将拒绝与科普相关 C# 的 issue , 望谅解.
    目前已有的模板:

    模板名 用途
    NClass 构建类型脚本
    NStuct 构建结构体脚本
    NEnum 构建枚举脚本
    NInterface 构建接口脚本
    NRecord 构建记录脚本
    NDelegate 快速创建委托
    FastOperator 快速创建方法的操作类
    FakeOperator 方法复制的操作类

    使用方法

    创建类

    
    //万年不变的预热
    NatashaInitializer.Preheating();
    
    //在随机域内创建一个类型
    NClass builder = NClass.RandomDomain();
    
    var type = builder
        .Public()
        .Summary("This is a test class;")
        /*
         namespace NatashaDynimacSpace
         {
           /// <summary>
           /// This is a test class;
           /// </summary>
           public class Nee7e202ee18c413dacae62af6b106c6e
        */
    
    
        .PublicReadonlyField<int>("ReadonlyField")
        //public readonly System.Int32 ReadonlyField;
    
    
        .Ctor(item => item.Public().Body("ReadonlyField = 10;"))
        /*
         public Nee7e202ee18c413dacae62af6b106c6e()
         {
                  ReadonlyField = 10;
         }
        */
    
    
        .PrivateField<string>("_name", "[MyTestAttribute]")
        //[MyTestAttribute]
        //private System.String _name;
    
    
        .Property(item => item
            .Public()
            .Attribute<MyTestAttribute>()
            .Type<string>()
            .Name("NameProperty")
            .OnlyGetter("return _name;"))
         /*[NatashaFunctionUT.Template.Compile.MyTestAttribute]
         public System.String NameProperty
         {
                get
                {
                    return _name;
                }
         }*/
    
    
        .Property(item => item
            .Public()
            .Type("AnotherClass")
            .Name("AnotherProperty"))
        //public AnotherClass AnotherProperty { get; set; }
    
    
        .Method(item => item
            .Public()
            .Virtrual()
            .Async()
            .Name("SetName")
            .Param<string>("name")
            .Body(@"_name = name;return _name;")
            .Return<Task<string>>())
         /*
          public virtual async System.Threading.Tasks.Task<System.String> SetName(System.String name)
          {
                _name = name;
                return _name;
          }
        */
    
        .NamespaceBodyAppend("public class AnotherClass{}")
        /*
         public class AnotherClass
         {
         }
        */
        .GetType();
    
    

    创建结构体

    //创建一段如下的结构
    /*
    [StructLayout(LayoutKind.Explicit)]
    public struct EnumUT1
    {
        [System.Runtime.InteropServices.FieldOffsetAttribute(0)]
        public System.Int32 Apple;
        [System.Runtime.InteropServices.FieldOffsetAttribute(0)]
        public System.Int32 Orange;
    }";
    */
    NStruct builder = NStruct.RandomDomain();
               
    var type = builder
      .HiddenNamespace()
      .AttributeAppend("[StructLayout(LayoutKind.Explicit)]")
      .Access(AccessFlags.Public)
      .Name("EnumUT1")
      .Field(item => { item.AttributeAppend<FieldOffsetAttribute>("0").Public().Name("Apple").Type<int>(); })
      .Field(item => { item.AttributeAppend<FieldOffsetAttribute>("0").Public().Name("Orange").Type<int>(); })
      .GetType();
    var script = builder.AssemblyBuilder.SyntaxTrees[0].ToString();
    

    创建枚举

    //创建以下枚举
    /*
    public enum EnumUT1
    {
        /// <summary>
        /// 苹果
        /// </summary>
        Apple = 1,
        Orange = 2,
        Banana
    }
    */
    NEnum builder = NEnum.RandomDomain();
               
    var type = builder
      .NoGlobalUsing()
      .HiddenNamespace()
      .Access(AccessFlags.Public)
      .Name("EnumUT1")
      .EnumField("Apple", 1,"苹果")
      .EnumField("Orange", 2)
      .EnumField("Banana")
      .GetType();
    var script = builder.AssemblyBuilder.SyntaxTrees[0].ToString();
    
    

    创建接口

    //创建以下接口
    /*
    using System;
    
    public interface Interface1
    {
        System.String Abc { get; set; }
    
        System.Int32 Test(System.String p);
    }
    */
    
    var builder = NInterface.RandomDomain();
    var type = builder
        .NoGlobalUsing()
        .HiddenNamespace()
        .Access(AccessFlags.Public)
        .Name("Interface1")
        .Property(item => item.Type<string>().Name("Abc"))
        .Method(item => item.Name("Test").Param<string>("p").Return<int>())
        .GetType();
    var script = builder.AssemblyBuilder.SyntaxTrees[0].ToString();
    

    使用 NDelegate 快速创建委托

    NDelegate 实现了自定义委托/系统委托( Action & Func ) 的创建方法.
    委托的参数名/参数类型/返回值与系统委托一一对应.
    针对系统委托,如果在添加方法体时还不清楚对应的参数名可以 F12 到对应的 Action/Func 定义中查看参数名.

    以下举例了常见的系统委托参数名

    • Action<T1> 定义的参数名为 obj; 而 Action<T1,T2> 参数名为: arg1 , arg2;
    • Func<T1,R> 定义的参数名为 arg; 而 Func<T1,T2,R> 参数名为: arg1 , arg2;

    使用代码:

    • 用法1: 自定义委托
    public delegate int TestDelegate(string value);
    var action = NDelegate
                  .RandomDomain()
                  .Delegate<TestDelegate>(@"return (value+""hello"").Length;");
    int result = action("Hello");
    
    • 用法2: 系统委托
    var action = NDelegate
                  .RandomDomain()
                  //创建非托管的异步委托,对应的系统委托: Func<string, string, Task<string>>
                  .UnsafeAsyncFunc<string, string, Task<string>>(@"return arg1 +"" ""+ arg2;");
    
    string result = await action("Hello", "World1!");
    Assert.Equal("Hello World1!", result);
    

    另外,我将在这个目录下上传一些奇奇怪怪的构建,包括一些新科技的应用,和有趣的语义扩展. UT链接

    其他 API

    模板比起基础构建,除了提供了方便的链式 API ,还有 Using 管理.

    • NoGlobalUsing()/UseGlobalUsing(): 是否使用默认(全局)域 using 覆盖.(默认使用)
    • LoadDomainUsing()/NotLoadDomainUsing(): 是否加载模板所在随机域中的 using.(默认使用)

    结尾

    实际上 Natasha 模板是针对大部分 C# 的数据类型进行的基础封装, 还可以进一步定制封装,比如以 NClass 为基础创建一个 Web COntroller 模板, 如果需要其他扩展, 可以先了解一下源码结构,或与我讨论进行扩展.

  • 相关阅读:
    48、C++ Primer 4th 笔记,句柄类,继承,虚函数等的一个综合例子(未完)
    79、在linux的man手册当中,man(1)是什么意思?
    ASP.NET2.0 ObjectDataSource的使用详解(1)
    ndts 一个使用不多重要命令
    ASP.NET2.0 ObjectDataSource的使用详解(2)
    使用自定义参数
    一步一步学习ObjectDataSource--(3)
    ASP.NET2.0快速入门--绑定到对象板(后来才发现,忘了)
    关于URL路径的基本使用
    ASP.NET2.0 快速入门 使用主题对站点进行自定义
  • 原文地址:https://www.cnblogs.com/NMSLanX/p/15814781.html
Copyright © 2020-2023  润新知