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. Spring学习(四)在Web项目中实例化IOC容器

    1.前言 前面我们讲到Spring在普通JAVA项目中的一些使用.本文将介绍在普通的Web项目中如何实例化Spring IOC容器.按照一般的思路.如果在Web中实例化Ioc容器.这不得获取Conte ...

  2. JAVA调用阿里云短信接口

    官方文档:https://help.aliyun.com/document_detail/101414.html?spm=a2c4g.11186623.6.626.2cef6220yxh5l7 jar ...

  3. layDate设置开始日期选择框和结束日期选择框 之间的相互验证方法

    var startDate = laydate.render({ elem: '#_select_start_date', //结束日期框的ID type: 'date', done: functio ...

  4. 【LeetCode】684. Redundant Connection 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 并查集 日期 题目地址:https://leetco ...

  5. 1307 - Counting Triangles

    1307 - Counting Triangles    PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 ...

  6. 深度学习中常见的 Normlization 及权重初始化相关知识(原理及公式推导)

    Batch Normlization(BN) 为什么要进行 BN 防止深度神经网络,每一层得参数更新会导致上层的输入数据发生变化,通过层层叠加,高层的输入分布变化会十分剧烈,这就使得高层需要不断去重新 ...

  7. Java GUI 桌面应用开发

    前言 虽然现在已经很少项目会涉及GUI技术,但作为一个合格的Java开发工程师,还是得了解才得 本文记录,idea使用JFormDesigner插件进行Java GUI 桌面应用开发 GUI Swin ...

  8. css怎么实现雪人

    冬天来了,怎么能少的了雪人呢,不管是现实中还是程序员的代码中统统都的安排上,那就一次安排几个雪人兄弟,咱们先看效果图: 有喜欢的就赶紧cv拿走吧!!! 其详细代码如下: 图1 html部分: < ...

  9. SpringMVC+Spring+Mybatis实现登录注册Demo

    使用环境:MyEclipse/Eclipse + Tomcat + MySql. 使用技术:SpringMVC + Spring + Mybatis. 实现效果 登录页面: 密码错误提示 登录成功后 ...

  10. find 命令常用解释

    背景色是:orange #### find命令 find * path: 所有搜索的目录以及其所有子目录.默认为当前目录 * expression: 所有搜索的文件的特征 * cmd: 对搜索结果惊醒 ...