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 模板, 如果需要其他扩展, 可以先了解一下源码结构,或与我讨论进行扩展.
Natasha 4.0 探索之路系列(四) 模板 API的更多相关文章
- Natasha 4.0 探索之路系列(一) 概况
Natasha 简介 Natasha 是一个基于 Roslyn 的动态编译类库, 它以极简的 API 完成了动态编译的大部分功能, 使用它可以在程序运行时编译出新的程序集. Natasha 允许开发人 ...
- Natasha 4.0 探索之路系列(三) 基本的动态编译
Natasha 的设计 动态编译 Roslyn 为开发者提供了动态编译的接口, 允许我们以 C# 代码来编写 Emit 或 表达式树生成的程序集, 但是完成一个编译需要诸多步骤, 用户参与的操作也很多 ...
- Natasha 4.0 探索之路系列(二) "域"与插件
域与ALC 在 Natasha 发布之后有不少小伙伴跑过来问域相关的问题, 能不能兼容 AppDomain, 如何使用 AppDomain, 为什么 CoreAPI 阉割了 AppDomain 等一系 ...
- go微服务系列(四) - http api中引入protobuf
1. protobuf相关依赖安装 2. 改造之前的client 2.1 新建proto文件 2.2 运行protoc命令生成go文件 2.3 然后把原来的map修改成具体的类型就可以了 3. 处理j ...
- C#中的函数式编程:递归与纯函数(二) 学习ASP.NET Core Razor 编程系列四——Asp.Net Core Razor列表模板页面
C#中的函数式编程:递归与纯函数(二) 在序言中,我们提到函数式编程的两大特征:无副作用.函数是第一公民.现在,我们先来深入第一个特征:无副作用. 无副作用是通过引用透明(Referential ...
- 转:arcgis api for js入门开发系列四地图查询
原文地址:arcgis api for js入门开发系列四地图查询 arcgis for js的地图查询方式,一般来说,总共有三种查询方式:FindTask.IdentifyTask.QueryTas ...
- Kubernetes系列(四) StatefulSet
作者: LemonNan 原文地址: https://juejin.im/post/6870071267438329869 Kubernetes系列(四) StatefulSet Kubernetes ...
- S5PV210开发系列四_uCGUI的移植
S5PV210开发系列四 uCGUI的移植 象棋小子 1048272975 GUI(图形用户界面)极大地方便了非专业用户的使用,用户无需记忆大量的命令,取而代之的是能够通过窗体.菜单 ...
- SQL Server 2008空间数据应用系列四:基础空间对象与函数应用
原文:SQL Server 2008空间数据应用系列四:基础空间对象与函数应用 友情提示,您阅读本篇博文的先决条件如下: 1.本文示例基于Microsoft SQL Server 2008 R2调测. ...
随机推荐
- Spring学习(四)在Web项目中实例化IOC容器
1.前言 前面我们讲到Spring在普通JAVA项目中的一些使用.本文将介绍在普通的Web项目中如何实例化Spring IOC容器.按照一般的思路.如果在Web中实例化Ioc容器.这不得获取Conte ...
- JAVA调用阿里云短信接口
官方文档:https://help.aliyun.com/document_detail/101414.html?spm=a2c4g.11186623.6.626.2cef6220yxh5l7 jar ...
- layDate设置开始日期选择框和结束日期选择框 之间的相互验证方法
var startDate = laydate.render({ elem: '#_select_start_date', //结束日期框的ID type: 'date', done: functio ...
- 【LeetCode】684. Redundant Connection 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 并查集 日期 题目地址:https://leetco ...
- 1307 - Counting Triangles
1307 - Counting Triangles PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 ...
- 深度学习中常见的 Normlization 及权重初始化相关知识(原理及公式推导)
Batch Normlization(BN) 为什么要进行 BN 防止深度神经网络,每一层得参数更新会导致上层的输入数据发生变化,通过层层叠加,高层的输入分布变化会十分剧烈,这就使得高层需要不断去重新 ...
- Java GUI 桌面应用开发
前言 虽然现在已经很少项目会涉及GUI技术,但作为一个合格的Java开发工程师,还是得了解才得 本文记录,idea使用JFormDesigner插件进行Java GUI 桌面应用开发 GUI Swin ...
- css怎么实现雪人
冬天来了,怎么能少的了雪人呢,不管是现实中还是程序员的代码中统统都的安排上,那就一次安排几个雪人兄弟,咱们先看效果图: 有喜欢的就赶紧cv拿走吧!!! 其详细代码如下: 图1 html部分: < ...
- SpringMVC+Spring+Mybatis实现登录注册Demo
使用环境:MyEclipse/Eclipse + Tomcat + MySql. 使用技术:SpringMVC + Spring + Mybatis. 实现效果 登录页面: 密码错误提示 登录成功后 ...
- find 命令常用解释
背景色是:orange #### find命令 find * path: 所有搜索的目录以及其所有子目录.默认为当前目录 * expression: 所有搜索的文件的特征 * cmd: 对搜索结果惊醒 ...