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

Natasha 4.0 探索之路系列(四) 模板 API的更多相关文章

  1. Natasha 4.0 探索之路系列(一) 概况

    Natasha 简介 Natasha 是一个基于 Roslyn 的动态编译类库, 它以极简的 API 完成了动态编译的大部分功能, 使用它可以在程序运行时编译出新的程序集. Natasha 允许开发人 ...

  2. Natasha 4.0 探索之路系列(三) 基本的动态编译

    Natasha 的设计 动态编译 Roslyn 为开发者提供了动态编译的接口, 允许我们以 C# 代码来编写 Emit 或 表达式树生成的程序集, 但是完成一个编译需要诸多步骤, 用户参与的操作也很多 ...

  3. Natasha 4.0 探索之路系列(二) "域"与插件

    域与ALC 在 Natasha 发布之后有不少小伙伴跑过来问域相关的问题, 能不能兼容 AppDomain, 如何使用 AppDomain, 为什么 CoreAPI 阉割了 AppDomain 等一系 ...

  4. go微服务系列(四) - http api中引入protobuf

    1. protobuf相关依赖安装 2. 改造之前的client 2.1 新建proto文件 2.2 运行protoc命令生成go文件 2.3 然后把原来的map修改成具体的类型就可以了 3. 处理j ...

  5. C#中的函数式编程:递归与纯函数(二) 学习ASP.NET Core Razor 编程系列四——Asp.Net Core Razor列表模板页面

    C#中的函数式编程:递归与纯函数(二)   在序言中,我们提到函数式编程的两大特征:无副作用.函数是第一公民.现在,我们先来深入第一个特征:无副作用. 无副作用是通过引用透明(Referential ...

  6. 转:arcgis api for js入门开发系列四地图查询

    原文地址:arcgis api for js入门开发系列四地图查询 arcgis for js的地图查询方式,一般来说,总共有三种查询方式:FindTask.IdentifyTask.QueryTas ...

  7. Kubernetes系列(四) StatefulSet

    作者: LemonNan 原文地址: https://juejin.im/post/6870071267438329869 Kubernetes系列(四) StatefulSet Kubernetes ...

  8. S5PV210开发系列四_uCGUI的移植

    S5PV210开发系列四 uCGUI的移植 象棋小子          1048272975 GUI(图形用户界面)极大地方便了非专业用户的使用,用户无需记忆大量的命令,取而代之的是能够通过窗体.菜单 ...

  9. SQL Server 2008空间数据应用系列四:基础空间对象与函数应用

    原文:SQL Server 2008空间数据应用系列四:基础空间对象与函数应用 友情提示,您阅读本篇博文的先决条件如下: 1.本文示例基于Microsoft SQL Server 2008 R2调测. ...

随机推荐

  1. Postman环境变量的使用

    前言 请注意,Postman新版有ui上的改动,本文使用的Postman 版本8.4.0 for Mac, ui有调整,但是功能无改变. Postman是一款接口调测的软件,服务端开发的同学肯定会对自 ...

  2. C++ NFS挂载

    挂载NFS 挂载命令 挂载NFS时,常用的命令比如: #将远程目录挂载到本地/home/share目录下 mount -t nfs -o nolock 192.168.1.10:/tmp /home/ ...

  3. Mysq索引优化(什么情况创建索引,什么情况不创建索引)

    一.以下情况需要创建索引 1.主键自动建立唯一索引 2.频繁作为查询条件的字段应该创建索引 3.查询中与其他表关联的字段,外键关系建立索引 4.单键/组合索引的选择问题,组合索引性价比更高 5.查询中 ...

  4. ByteBuddy代码生成技术

    简介 如官网所说Byte Buddy 是一个代码生成和操作库,用于在Java应用程序运行时创建和修改Java类,而无需编译器的帮助.除了Java类库附带的代码生成实用程序外,Byte Buddy还允许 ...

  5. c++设计模式概述之代理

    代码写的不规范,目的是缩短文章篇幅,实际中请不要这样做. 1.模式的结构 代理模式的主要角色如下: A.抽象主题(Subject)类:通过接口或抽象类声明真实主题和代理对象实现的业务方法. B.真实主 ...

  6. wordpress中遇到的问题

    在博客园申请了账号,也已经开始写了两篇内容,但还是想要有属于自己的小站.于是将域名续费了几年,又在我之前买的vps上搭建了一个wordpress博客站点,这样以后我就可以同时发布到两个地方. 根据教程 ...

  7. VS Code 如何设置大小写转换快捷键

    一般情况下,快捷键如下: 转换为大写:Ctrl+Shift+u 转换为小写:Ctrl+Shift+l 如果不行的话,需要单独进行设置,步骤如下: 1.点击[文件]-[首选项]-[键盘快捷方式]菜单: ...

  8. 以简御繁——介绍IOC

    1.IOC的理论背景 大家开发理念,一直都是奔着架构稳定.低耦合性.而IOC初衷,就是为了解决模块依赖问题,理解<六大设计原则(SOLID)> 如图所示,在我们开发中,业务的实现,就是靠着 ...

  9. Dapper in .Net Core

    一.前言 关于什么是Dapper,在此不做赘述:本文仅对Dapper在.Net Core中的使用作扼要说明,所陈代码以示例讲解为主,乃抛砖引玉,开发者可根据自身需要进行扩展和调整:其中如有疏漏之处,望 ...

  10. 编写Java程序,使用菜单组件制作一个记事本编辑器

    返回本章节 返回作业目录 需求说明: 使用菜单组件制作一个记事本编辑器 实现思路: 创建记事本菜单工具栏JMenuBar. 创建多个菜单条JMenu. 创建多个菜单项JMenuItem. 将菜单添加至 ...