简单至极 C# 调用 aardio

admin2022-01-13  4.6K+

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 」:


转载请注明原文地址: https://aardio.net/read-295.html
最新回复(0)
aardio问答
aardio编程语言