Jacen He
.Net 4.0 开始添加了 dynamic 类型。
在 C# 里要实现一个 dynamic 对象还是略有些啰嗦的,不过 aardio 对象会自动支持 .Net 的 dynamic 类型。在 C# 中只要将传入的 aardio 对象类型声明为 dynamic 类型,就可以用更简洁的语法调用 aardio 对象。
下面我们先看 C# 接收和调用 aardio 对象的代码:
using System;
using System.Dynamic;
namespace CSharpLibrary
{
public class CSharpObject
{
public object Hello( dynamic aardioObject ){
//修改 aardio 对象属性
aardioObject.属性名 = 456;
//调用 aardio 对象函数
var ret = aardioObject.执行aardio(" console.log('在C#中执行aardio代码') ");
//读 aardio 对象属性
return aardioObject.test.abc;
}
}
}
再看 aardio 调用 C# 的代码:
//自程序集导入名字空间
var CSharpLibrary = assembly.import("CSharpLibrary")
//使用 C# 编写的类构造对象实例
var cSharpObject = CSharpLibrary.CSharpObject();
var aardioObject = {
test = { abc = 12345; }
属性名 = 123;
执行aardio = function( code ){
loadcode(code)();
return 123;
}
}
//调用 C# 函数
var ret = cSharpObject.Hello(aardioObject);
console.dump(ret);
console.dumpJson(aardioObject);
console.pause();
以上范例完整源码请参考「aardio 范例 / 调用其他语言 / dotNet / 动态类型回调」:
如果你不想打开或没有安装 C# 开发环境,也没有关系,可以用 aardio 直接编译 C# 源码, 如下:
//动态类型回调
import console;
import dotNet.v4; //如果没有安装 .Net 4.x 则自动发装
//创建C#编译器
var compiler = dotNet.createCompiler("C#");
//必须引入下面的几个 DLL
compiler.Reference("System.dll")
compiler.Reference("System.Core.dll")
compiler.Reference("Microsoft.CSharp.dll")
//设置待编译C#源码
compiler.Source = /******
using System;
using System.Dynamic;
namespace CSharpLibrary
{
public class CSharpObject
{
public object Hello( dynamic aardioObject ){
//修改 aardio 对象属性
aardioObject.属性名 = 456;
//调用 aardio 对象函数
var ret = aardioObject.执行aardio(" console.log('在C#中执行aardio代码') ");
//读 aardio 对象属性
return aardioObject.test.abc;
}
}
}
******/
var assembly = compiler.Compile(); //编译并返回程序集
console.log(compiler.getLastError()); //查看编译器错误信息
var CSharpLibrary = assembly.import("CSharpLibrary"); //自程序集导入名字空间
//自程序集导入名字空间
var CSharpLibrary = assembly.import("CSharpLibrary")
//使用 C# 编写的类构造对象实例
var cSharpObject = CSharpLibrary.CSharpObject();
var aardioObject = {
test = { abc = 12345; }
属性名 = 123;
执行aardio = function( code ){
loadcode(code)();
return 123;
}
}
//调用实时编译的C#函数
var ret = cSharpObject.Hello(aardioObject);
console.dump(ret);
console.dumpJson(aardioObject);
console.pause();
只要在代码中用 import dotNet.v4; 替换原来的 import dotNet; aardio 就会自动检测 .Net 4.x 是否安装,没有安装会自动安装。不过 Win10, Win11 已经自带了 .Net 4.x ,依赖 .Net 4.x 的软件也很多,所以真正需要安装的时候并不多。
如果你想支持 .Net 2.x, .Net.3.x ,那就不能用 dynamic 类型了。例如获取 aardio 对象的属性,就只能这样写:
aardioObject.GetType().InvokeMember(
index,
BindingFlags.GetProperty,
null,
dispObject,
null
);
如果每读写一个属性都这样搞,那可真吃不消。我们可以在 C# 里实现一个用于封装 aardio 对象的类 —— 源码如下:
//用于封装 aardio 对象
public class DispatchObject : IEnumerable
{
private object dispObject;
//构造函数
public DispatchObject(object obj){
dispObject = obj;
}
//下标
public object this [string index]
{
get
{
return dispObject.GetType().InvokeMember(
index,
BindingFlags.GetProperty,
null,
dispObject,
null
);
}
set
{
dispObject.GetType().InvokeMember(
index,
BindingFlags.SetProperty,
null,
dispObject,
new object[] { value });
}
}
//调用成员函数
public object Invoke(string k,params/*不定个数参数*/ object[] arg ){
return dispObject.GetType().InvokeMember(k, BindingFlags.InvokeMethod, null, dispObject, arg );
}
//实现枚举接口
IEnumerator IEnumerable.GetEnumerator(){
return (dispObject as IEnumerable).GetEnumerator();
}
}
在 C# 中使用这个类调用 aardio 对象的例子:
DispatchObject dispObject = new DispatchObject( aardioObject );
//遍历 aardio 对象
foreach ( object item in dispObject)
{
Console.WriteLine( "C#中遍历aardio对象键名:" item );
}
dispObject["属性名"] = 456;
dispObject.Invoke( "执行aardio", " console.log('在C#中执行aardio代码') " );
var v = dispObject["属性名"];
是不是简单多了?!当然还是会被 dynamic 吊打。
以上范例完整源码请参考:「aardio 范例 / 调用其他语言 / dotNet / 回调 aardio 」:
主题数 170 | 今日评论 0 | 今日主题 0 |