【IronRuby】细谈Ironruby与.NET的互操作性

作者: Ray Linn 最后更新:2010/07/19

[b]引用.NET的Assembly[/b]
除了我们前面提到的require <PartialName> 和require <Strong name>外,Ironruby 1.0发布的时候,还提供了一个新的函数load_assembly,这个函数的参数为Assembly的名称,在内部,load_assembly会先调用Assembly.Load,如果找不到这个Assembly,那就再调用Assembly.LoadWithPartialName.它也支持require的两种调用方法。除此之外,load_assembly还可以接受第二个参数,指明只引用该Assembly下的某个名称空间,比如:
[code]
load_assembly 'IronRuby.Libraries', 'IronRuby.StandardLibrary.StringIO'
[/code]

[b]名称空间namespace[/b]
当装配件被加载之后,它的顶层名称空间和类在ironruby内是可见的。比如下面这个例子

namespace Models {
public class Person {
private string name;
public Person(string name) {
this.name = name;
}
public string Name {
get {
return name;
}
}
}

上面C#代码的名称空间“Models”与普通的ruby模块一样可被存取:

>>> require 'models'
=> true
>>> Models
=> Models
>>> Models.class
=> Module

需要注意几点:
1.不可用小写的名称空间:Ruby常量要求使用大写开头的名字,所以名称空间必须遵循Ironruby的要求。
2.不可用“空”的名称空间: 对IronRuby来说,名称空间不能为空。而且由于CLR的名称空间只在有可访问的子类时才存在,因此假如名称空间的所有子类都是私有的,IronRuby 将无法访问该名称空间。所以名称空间内至少要有一个公共的可访问类。

因为名称空间被视为Ironruby的普通模块,所以它和其他ruby模块一样,可以被mixin.


class MyApp
include "models"
.....
end


[b]使用C#的类[/b]

CLR中的类被视为普通的ruby类,这会为Ruby增加许多很有趣的特性。

[u]1. Ruby中的泛型。[/u]
泛型一直被视为减少代码错误的一种有效方式,CLR提供了完美的“膨胀法”的泛型实现,因此在ironruby中使用CLR的泛型集合,取代原有的ruby实现,不失为提高动态语言代码质量的一种方法。

#使用CLR中的泛型
dict = System::Collections::Generic::Dictionary[String, Array].new
#实际:System.Collections.Generic.Dictionary`2[IronRuby.Builtins.MutableString,IronRuby.Builtins.RubyArray]
dict['foo'] = [1,2,3]
#可以使用所有的ruby方法
dic['foo'].map{|x|x+1}
#下面代码会抛出异常
dict[23] = '34'
dict[23] = [4,5,6]


[u]2. Ruby中的GUI[/u]
Ruby中的类可以继承CLR中的类,因此可以使用CLR的WinForm为Ruby扩展出GUI而不需要类似Shoes之类的Ruby框架

require "System.Windows.Forms"
include System::Windows::Forms
class RForm < Form
end
f = RForm.new


[u]3.Reopen[/u]
如果想扩展CLR中的类,比如增加一个属性,有时候不需要大费周折去创建子类继承父类。CLR中的类一样可以被打开添加属性或者方法

class Models::Person
attr_reader :age
class << self
alias super_new new
def new(name, age)
instance = super_new(name)
instance.instance_variable_set(:"@age", age)
instance
end
end
end

Person.new("Jimmy", 25)

[b]方法[/b]

方法里值得一提的是,有些.NET方法带有out修饰,比如:

public string Foo(int i, out int j, out int k);


该方法等价于:

return_value, j, k = Foo(5)


同样带有ref修饰的:

bool Foo(string a, out string b, string c, ref string d, string e, out string f);

等价于

return_value, b_out, d_out, f_out = foo('a_in ', 'c_in ', 'd_in', 'e_in ')


由于.NET里许多类被映射成Ruby的类,在许多时候可能会出现语义不清的状态,比如.NET和Ruby的String类,都带有replace方法,因此Ironruby也提供了一些方法,用于澄清语义。

to_clr_type:返回CLR里的实际类型
clr_member:指明调用CLR里的方法、属性或者字段,如System::String.new("a").clr_member(:Replace).call("a", "b")
clr_ctor: 某些类比如Thread被映射成IronRuby的类,clr_ctor可以让你指明调用原来.NET类的构造函数。
to_clr_string:由于CLR的String和Ruby的String不是同一个类,这个方法会返回CLR的String类型。

[b]枚举[/b]
Enum在ironruby中被视为普通的类,可以直接被使用

require 'System.Windows.Forms'
include System::Windows::Forms
System::Enum.GetNames(AnchorStyles.to_clr_type)
AnchorStyles.bottom | AnchorStyles.left


[b]事件[/b]
在Ironruby中响应CLR中的事件有好几种方法:

1.最基础的方法,使用代码块(Block)

require "System.Windows.Forms"
button = System::Windows::Forms::Button.new
button.click { |sender, e| puts "Click!" }
button.perform_click


2.使用Proc对象,这个方法在必要事可以移除响应代码。

require "System.Windows.Forms"
button = System::Windows::Forms::Button.new
on_click = proc { |sender, e| puts "Click!" }
button.click(&on_click)
button.perform_click
button.click.remove(on_click)
button.perform_click


我们陈述了一些Ironruby和CLR互动的一些细节问题,这些是Ironruby有别于其他ruby实现的方面,体现了基于CLR实现Ruby的许多优点。值得一提的是,Ironruby是遵循Ruby规范的实现,大部分Ruby代码都可以在上面无缝运行,比如rails。

总结一下Ironruby和CLR通讯需要注意的一些问题:

1.CLR的名称空间和接口必须首字大写,以便映射到ruby的模块。
2.CLR的类必须首字大写以便映射成Ruby类。
3.CLR的方法可以按原有的方法名调用,也可以用ruby风格的方法名调用,即“骆驼式命名法”或 "Mangling命名法"皆可。
4.CLR的虚方法可以在Ironruby用上述二种命名法重写。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值