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

e2f2fdfd02f1298da25deb08c1440477.png

相关文章

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 模板, 如果需要其他扩展, 可以先了解一下源码结构,或与我讨论进行扩展.

fde44f6deef9821f2fdb04468a48cb28.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值