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. Miniconda入门教程

    Miniconda 教程 介绍 Anaconda指的是一个开源的Python发行版本,其包含了conda.Python等180多个科学包及其依赖项.因为包含了大量的科学包,Anaconda 的下载文件 ...

  2. 《Java必须知道的300个问题》读书总结

    这本书是在图书馆随便逛的时候找到的书.花了一下午看完了,感觉有用的地方不是很多,大部分都是些概念,并没有太大用途.不过里边有些东西还是可以看一看的,总结如下. Java语言基础 1.表达式3-2.6= ...

  3. 【LeetCode】 204. Count Primes 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 素数筛法 参考资料 日期 [LeetCode] 题目 ...

  4. 【LeetCode】120. Triangle 解题报告(Python)

    [LeetCode]120. Triangle 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址htt ...

  5. 【LeetCode】154. Find Minimum in Rotated Sorted Array II 解题报告(Python)

    [LeetCode]154. Find Minimum in Rotated Sorted Array II 解题报告(Python) 标签: LeetCode 题目地址:https://leetco ...

  6. C. Unfair Poll

    http://codeforces.com/problemset/problem/758/C C. Unfair Poll time limit per test 1 second memory li ...

  7. Mybatis源码系列 执行流程(一)

    1.Mybatis的使用 public static void main(String[] args) throws IOException { //1.获取配置文件流 InputStream is ...

  8. springboot中word转pdf,加盖电子印章

    概述 在开发过程中,word转pdf的方式有很多种有jar包的方式,有安装openoffice的方式,但是使用有的jar包有license认证,不然会生成水印,综合几种方法我采用了libreoffic ...

  9. oralce索引中INDEX SKIP SCAN 和 INDEX RANGE SCAN区别

    INDEX SKIP SCAN 当表中建立有复合索引的时候,查询时,除复合索引第一列外,别的列作为条件时,且优化器模式为CBO,这个时候查询可能会用到INDEX SKIP SCAN skip scan ...

  10. <学习opencv>opencv数据类型

    目录 Opencv数据类型: 基础类型概述 固定向量类class cv::Vec<> 固定矩阵类cv::Matx<> 点类 Point class cv::Scalar 深入了 ...