Particular Script# Scenario and semantics
大家好..前段时间考试,所以影响更新进度,没法..
这一部分是谈,Script#的加入给C#带来的变化,和Scirpt#在编程中的一些特性,其中特别是可以将一些JavaScript的方法带入到C#中来,使得在编写代码时有很多便利.有以下内容
一:How Do I Accomplish a Particular Script Scenario?
(1)Using eval to Execute Code and Perform JSON Deserializtion?
(2)Performing Late-bound Member Access
(3)Deleting a Field from an Object
(4)Enumerating Members of an Object
(5)Retrieving The Native Script Type of an Object
(6)Defining and Implementing Global Methods
(7)Invoking Global Methods
(8)Definfing Nested Functions to Implement Closures
(9)Create and Using Plain Script or JSON Objects
二:How is a Particular C# Feature Modeled in Script?
(1)How is a Namespace Defined?
(2)how is a Class Defined?
(3)How is a Derived Class Defined?
(4)How is an Interface Defined?
(5)How is a Delegate Type Defined?
(6)How are Delegates Used?
(7)How are Enumerations Defined and Consumed?
(8)How are Properties Declared and Accessed?
(9)How are Indexers Declared and Accessed?
(10)How are Events Declared and Accessed?
(11)How are Static Members Declared and Accessed?
(12)How is a foreach Statement Implemented?
(13)How are Anonymous Delegates Implemented
到这里ScriptSharp.pdf就翻译完成了.希望对大家使用Script#开发能有所帮助,接下来我会写Script#与ASP.NET AJXA的结合和Script#中那就.dll文件的研究,谢谢大家关注.有什么不好请多指点哦!
How Do I Accomplish a Particular Script Scenario?
这部分提供一些普通的scripting场景,有些Script相对于C#是特有的场景.还介绍对C#的提取或compiler支持的授权script场景 .
Using eval to Execute Code and Perform JSON Deserializtion?
Script 已经有一个全局(global)的eval函数允许你执行JavaScript代码或将你的表现形式为String的通过JavaScript deserialize为对象.
可是,在之前全局(global)方法是不允许在C#中使用的.这个功能被暴露(exposed )给C#开发者使用Script.Eval 方法来实现.Script.Eval可是不在一个运行时刻中提取的.而是依靠编译器在本地产生的Script中的的eval方法来实现的.
// C# string code = ;
object result = Script.Eval(code);
// Generated Script
var code = ;
var result = eval(code);
object result = Script.Eval(code);
// Generated Script
var code = ;
var result = eval(code);
关键的就是eval是利用编译JSON字面如deserialization的部分.Script.Eval方法能像下面样使用:
//C#
object data = Script.Eval(“[ { name: "abc‟, value: 123 } ]”);
object data = Script.Eval(“[ { name: "abc‟, value: 123 } ]”);
Using alert,prompt and Related Methods(后期绑定)
同样是普通的Script 全局( global)方法如alert,prompt,confirm都是在DHTML window object的存在的方法.就像刚才eval method方法, Script类包含这些APIs,他们是被编译器转换后的Script典型用法.
// C# Script.Alert(msg);
// Generated Script alert(msg);
// Generated Script alert(msg);
Script允许在后期绑定方式(late-bound manner )中离开任何对象访问fields或invoking方法.C#在其他方面没有支持后期绑定的代码.因此Script#提供一个组APIs允许你在Script产生时刻为其制作明确(explicit )的后期绑定代码(late-bound code )转为暗示(implicit )后期绑定.
Script#还引入通过get/set访问者方法实现的Properties的概念,和使用add/remove访问者方法实现事件的概念.后期绑定更好的访问,扩展这些高级概念.
如下是例,你能使用后期绑定访问一个在编译时刻的成员名,这个成员是一个常量.或是一个变量.两种模式工作,并产生最少的script,这样的效果全是利用Script的动态性特性.
// C#
object o = ;
string fieldName = ;
object value = Type.GetField(o, “aaa”);
Type.SetField(o, “aaa”, value);
Type.SetField(o, fieldName, value);
// Generated Script
var o = ;
var fieldName = ;
var value = o.aaa;
o.aaa = value;
o[fieldName] = value;
// C# object o = ;
string methodName = ;
object result = Type.InvokeMethod(o, “doFoo”, param1, param2);
Type.InvokeMethod(o, methodName, param1);
// Generated Script
var o = ;
var result = o.doFoo(param1, param2);
o[methodName](param1);
// C# object o = ;
string propName = ;
object value = Type.GetProperty(o, “foo”);
Type.SetProperty(o, “foo”, value);
Type.SetProperty(o, propName, value);
// Generated Script
var o = ;
var propName = ;
var value = o.get_foo();
o.set_foo(value);
o[„set_‟ + propName](value);
object o = ;
string fieldName = ;
object value = Type.GetField(o, “aaa”);
Type.SetField(o, “aaa”, value);
Type.SetField(o, fieldName, value);
// Generated Script
var o = ;
var fieldName = ;
var value = o.aaa;
o.aaa = value;
o[fieldName] = value;
// C# object o = ;
string methodName = ;
object result = Type.InvokeMethod(o, “doFoo”, param1, param2);
Type.InvokeMethod(o, methodName, param1);
// Generated Script
var o = ;
var result = o.doFoo(param1, param2);
o[methodName](param1);
// C# object o = ;
string propName = ;
object value = Type.GetProperty(o, “foo”);
Type.SetProperty(o, “foo”, value);
Type.SetProperty(o, propName, value);
// Generated Script
var o = ;
var propName = ;
var value = o.get_foo();
o.set_foo(value);
o[„set_‟ + propName](value);
Deleting a Field from an Object
删除操作,在Script允许从一个对象中删除一个成员field.这不同于简单的将field的值设置为Null.
// C# object o = ;
Type.DeleteField(o, “xyz”);
// Generated Script
var o = ;
delete o.xyz;
Type.DeleteField(o, “xyz”);
// Generated Script
var o = ;
delete o.xyz;
Enumerating Members of an Object
Script允许利用"for"去为任意对象的成员声明枚举.Script#授权你在一个Dictionary中用foreach使用枚举去设置Dictionary成员中的DictionaryEntry objects.Dictionary它自己呈现一个任何,明确的javaScript object.
// C# Dictionary d = ;
foreach (DictionaryEntry entry in d)
{ // Use entry.Key and entry.Value }
// Generated Script
for (var $key in d)
{
var entry = { key: $key, value: d[$key] };
}
foreach (DictionaryEntry entry in d)
{ // Use entry.Key and entry.Value }
// Generated Script
for (var $key in d)
{
var entry = { key: $key, value: d[$key] };
}
Script实际允许你为任何对象的成员使用枚举并且不需要明确的JavaScript objects.为支持这样的场景,Script#允许你在你的C#代码中为任意object创建一个Dictionary使用枚举,如下面描述.
// C#
MyClass c = ;
foreach (DictionaryEntry entry in Dictionary.GetDictionary(c)) { }
// Generated Script
var c = ;
for (var $key in c)
{
var entry = { key: $key, value: c[$key] };
}
MyClass c = ;
foreach (DictionaryEntry entry in Dictionary.GetDictionary(c)) { }
// Generated Script
var c = ;
for (var $key in c)
{
var entry = { key: $key, value: c[$key] };
}
Retrieving The Native Script Type of an Object
这个Script一个对象的类型被Script引擎跟踪.它也许可能是"Object","Number","Boolean","String","Function"或"undefined".这样的不同于关于对象的GetType()方法,会返回的详细class的相应的instance的类型.
//C#
object o = ;
if (Type.GetScriptType(o) == “undefined”)
{ }
// Generated Script var o = ;
if (typeof(o) == „undefined‟)
{ }
object o = ;
if (Type.GetScriptType(o) == “undefined”)
{ }
// Generated Script var o = ;
if (typeof(o) == „undefined‟)
{ }
Defining and Implementing Global Methods
当全局(global)方法受到很强的阻塞时,有时你想简单需要他们.需要能出现当你要定义一个系统assembly并需要呈现现有global APIs时,或当你必须产生一个能和其他的现有的script交互的全局(global)方法,或如果你想要有产生一个事件操作者,你将需要把元素的事件钩在一个HTML markup元素中的属性内.
你能创建一个static类并注释这个关于GlobalMembers类metadata属性(attribute)的类.所有的方法和这个类的properties被提升到顶级全局成员.如一个类可能不包括fields或事件.
// C#
[GlobalMethods]
public static class PageImplementation {
public static void OnBodyLoad() { }
}
// Generated Script function onBodyLoad()
{ }
[GlobalMethods]
public static class PageImplementation {
public static void OnBodyLoad() { }
}
// Generated Script function onBodyLoad()
{ }
Invoking Global Methods
你能使用技术描述上面定义一个类的static方法去表现为全局(global)方法,并使用这些static APIs去调用他们.如果你需要调用全局(global)方法在一个late-bound 方式,你只需要知道方法名就行,你能使用Type.InvokeMethod(使用late-bound访问成员方法如下面).
//C#
object result = Type.InvokeMethod(null,"doFoo",param1,param2);
//Generated Script
var result = doFoo(param1,param2);
object result = Type.InvokeMethod(null,"doFoo",param1,param2);
//Generated Script
var result = doFoo(param1,param2);
Definfing Nested Functions to Implement Closures
内部函数和Closures被模型化在C#中使用匿名delegate
// C#
public delegate void XyzDelegate(int i);
public class MyClass {
private int _data;
public void MyMethod(object o)
{
int localData = 0;
DoStuff(o, delegate(int i)
{
_data = localData + i + MyClass.GlobalData; });
}
public void DoStuff(object o, XyzDelegate callback)
{
// Some code, including code that invokes the delegate passed in
}
}
// Generated Script
MyClass = function() { }
MyClass.prototype = {
_data: 0,
myMethod: function(o)
{ var localData = 0;
nStuff.ScriptSharp.Tests.MyClass.doStuff(o, new Delegate(this, function(i) { this._data = localData + i + MyClass.GlobalData; })); },
doStuff: function(o, d)
{ // Some code, including code that invokes the delegate passed in }
}
MyClass.createClass('MyClass');
public delegate void XyzDelegate(int i);
public class MyClass {
private int _data;
public void MyMethod(object o)
{
int localData = 0;
DoStuff(o, delegate(int i)
{
_data = localData + i + MyClass.GlobalData; });
}
public void DoStuff(object o, XyzDelegate callback)
{
// Some code, including code that invokes the delegate passed in
}
}
// Generated Script
MyClass = function() { }
MyClass.prototype = {
_data: 0,
myMethod: function(o)
{ var localData = 0;
nStuff.ScriptSharp.Tests.MyClass.doStuff(o, new Delegate(this, function(i) { this._data = localData + i + MyClass.GlobalData; })); },
doStuff: function(o, d)
{ // Some code, including code that invokes the delegate passed in }
}
MyClass.createClass('MyClass');
Create and Using Plain Script or JSON Objects
首先要澄清什么是无格式Script对象.一个无格式Script对象本质上是一个对象的实例,更优于任何具体类(class).运行环境中每一个对象的类型是在字面上是一个"Object".(就像在Script中使用typeof返回类型样)
每一个对象的在C#中的模型是通过sealed类与[Record]metadata attribute 显示如下
namespace UI
{
[Record]
public sealed class Point
{
public int x;
public int y;
public Point(int x, int y)
{
this.x=x;
this.y=y;
}
}
}
Point p = new Point(10,100);
Type.createNamespace('UI');
UI.$Create_Point = function(x,y)
{
var $o={};
$o.x = x;
$o.y =y;
return $o;
}
var p = UI.$create_Point(10,100);
{
[Record]
public sealed class Point
{
public int x;
public int y;
public Point(int x, int y)
{
this.x=x;
this.y=y;
}
}
}
Point p = new Point(10,100);
Type.createNamespace('UI');
UI.$Create_Point = function(x,y)
{
var $o={};
$o.x = x;
$o.y =y;
return $o;
}
var p = UI.$create_Point(10,100);
你能看到Point object 实例正好是一个script无格式对象(plain-script object).在基本的一个plain-script object被本质相当于一个结合name/value对的集合,aka,a Dictionary.
一个有趣的场景就是无格式Script对象获得执行一个JSON字符串deserialized成为对象,deserialized Dictionaries在程序中不是友善.在一个强类型的语言C#中,在下面的例子会比较明显.你能利用records去定于一个shape/type的结构去允许友善的程序设计逆向未加工数据.
// C#
//without structs
string data = '{x:10,y:100}';
Dictionary d = (Dictionary)ScriptFX.JSON.Deserialize(data);
int x =(int)d["x"];
//with structs
Point p =(Point)ScriptFX.JSON.Deserialize(data);
int x = p.x;
//without structs
string data = '{x:10,y:100}';
Dictionary d = (Dictionary)ScriptFX.JSON.Deserialize(data);
int x =(int)d["x"];
//with structs
Point p =(Point)ScriptFX.JSON.Deserialize(data);
int x = p.x;
Create Plain JSON Objects
有时你需要创建一个Script对象,一个关于确定的设置完好的name/value对的Script对象,通常这个涉及无格式Script对象.虽然,你能利用上面所描述的固定和众所周知的设置name/value对的技术来实现,但有时你预先不知道field.如在C#对象是呈现一个Dictionary object.
这个Dictionary 对象支持一个对象的创造,你能添加fields.它还提供一个详细的构造器,用来带给创建一个对象时一个有序的name/value对.
// C#
Dictionary d1 = new Dictionary();
d1[“abc”] = 123;
d1[“xyz”] = true;
d1[“foo”] = “bar”;
Dictionary d2 = new Dictionary(“abc”, 123, “xyz”, true);
d2[“foo”] = “bar”;
// Generated Script var d1 = {};
d1[„abc‟] = 123; d1[„xyz‟] = true;
d1[„foo‟] = „bar‟ var d2 = { abc: 123, xyz: true };
d2[„foo‟] = „bar‟;
Dictionary d1 = new Dictionary();
d1[“abc”] = 123;
d1[“xyz”] = true;
d1[“foo”] = “bar”;
Dictionary d2 = new Dictionary(“abc”, 123, “xyz”, true);
d2[“foo”] = “bar”;
// Generated Script var d1 = {};
d1[„abc‟] = 123; d1[„xyz‟] = true;
d1[„foo‟] = „bar‟ var d2 = { abc: 123, xyz: true };
d2[„foo‟] = „bar‟;
Checking for Underfined
通常如果一个变量有值它需要检测它是不是undefined.还频繁检测变量的方式如果是null或如果是undefined,和没有错误的识别0,false,或empty 字符串,如null或undefined.Script#在Script class中提供这个方法.包括IsNull,IsNullOrUnderfined,和 IsUndefined.
//C#
void DoSomething(string o)
{
if(script.IsNullorUndefined(o))
{
return "";
}
}
//Generated script
function DoSomething(o)
{
//This test equates to:
//if((o===null)||(o===undefined))
if(isNullOrUndefined(o))
{
return "";
}
}
void DoSomething(string o)
{
if(script.IsNullorUndefined(o))
{
return "";
}
}
//Generated script
function DoSomething(o)
{
//This test equates to:
//if((o===null)||(o===undefined))
if(isNullOrUndefined(o))
{
return "";
}
}
How is a Particular C# Feature Modeled in Script?
这一部分提供关于C# 结构和模式与Script模型有什么不同.目标是最优的抽象级别,虽然显示的是使用的 C#-isms.
How is a Namespace Defined?
在Script中Namespaces被模仿通过一个对象脱离开全局窗口对象.
//C#
namespace Sample.Components{}
//Generated Script
Type.createNamespace('Sample.Components');
namespace Sample.Components{}
//Generated Script
Type.createNamespace('Sample.Components');
how is a Class Defined?
一个Script函数被使用来定义类型(并关联他的构造器),并类型成员被定义在prototype相联的函数中.这个函数注册一个类,允许核心类型系统去执行所需的类型初始化.
namespace Demo
{
public class Person
{
private string _name;
public Person(string name){..};
public string Name{
get{..}
}
}
}
/// Generated Script
Demo.Person = function(name)
{
.
}
Demo.Person.prototype =
{
_name:null;
get_Name:function(){}
};
Demo.Person.createClass('Demo.Person');
{
public class Person
{
private string _name;
public Person(string name){..};
public string Name{
get{..}
}
}
}
/// Generated Script
Demo.Person = function(name)
{
.
}
Demo.Person.prototype =
{
_name:null;
get_Name:function(){}
};
Demo.Person.createClass('Demo.Person');
注意 不同的访问修饰符像Internal,public,sealed,abstract等.在产生的Script中不显示.这些是强迫C#代码的级别的关键字.
How is a Derived Class Defined?
一系列派生类在注册时才指定继承.这个类型系统被实现在sscorlib.js中,确保派生类的成员正确的继承父类,并设置好这一系列动作,所以检测这个类是为基类类型的信息提供预期的结果.派生类构造器调用基类的构造器.
//C#
namespace Demo
{
public class Employee : Person
{
public Employee(string name):base(name){.}
}
}
//Generated Script
Demo.Employee = function(name){
Demo.Employee.initializeBase(this,[name]);
}
Demo.Employee.createClass('Demo.Employee',Demo.Person);
namespace Demo
{
public class Employee : Person
{
public Employee(string name):base(name){.}
}
}
//Generated Script
Demo.Employee = function(name){
Demo.Employee.initializeBase(this,[name]);
}
Demo.Employee.createClass('Demo.Employee',Demo.Person);
How is an Interface Defined?
使用Script函数定义interface类型.
//C#
public interface IDisposable
{
void Dispose();
}
//Generated Script
var IDisposable = function(){}
IDisposable.createInterface('IDisposable');
public interface IDisposable
{
void Dispose();
}
//Generated Script
var IDisposable = function(){}
IDisposable.createInterface('IDisposable');
--------------------------------------------
注意一个接口成员在产生的scrpt中没有被定义.这是因为在script中一个接口是简单的标记类型,能在运行时被检测到.所有接口的实现都被C#编译器执行的C#级别的代码.
//C#
public class Control:IDisposable
{
}
//Generated Script
var Control = fuction()
{
}
Control.createClass('Control',null,IDisposable);
public class Control:IDisposable
{
}
//Generated Script
var Control = fuction()
{
}
Control.createClass('Control',null,IDisposable);
How is a Delegate Type Defined?
在写C#代码时Delegates常被使用,但在script中没能定义他们.只不过在产生script时在这个函数中通过使用方法传递给现有的delegates.delegate的签名被C#编译器在C#代码级别时执行.
How are Delegates Used?
Delegates能被传递一个引用到的函数中创建.这个被创建的delegate会跟踪对象实例和函数的引用.
//C#
public class App
{
private void OnClick(object sender,EventArgs e){.};
private void Main(){
EventHandler handler = new EventHandler(this.OnClick);
}
}
//Generated script
App = function(){}
App.prototype =
{
_onClick:function(sender, e){}
_main:function(){
var handler = Delegate.create(this,this._onClick);
}
}
public class App
{
private void OnClick(object sender,EventArgs e){.};
private void Main(){
EventHandler handler = new EventHandler(this.OnClick);
}
}
//Generated script
App = function(){}
App.prototype =
{
_onClick:function(sender, e){}
_main:function(){
var handler = Delegate.create(this,this._onClick);
}
}
-----------------------------------
一个delegate已经被创建,它能完好的脱离一个event handler或callback到其他的组件上.这个组件能管理一个delegate的list.只要使用Delegate.Combine和 Delegate.Remove放就能达到你的期望.
//C#
public class Button
{
private Eventhandler _clickHandler;
public event Eventhandler click
{
add{
_clickHandler = (Eventhandler)Delegate.Combine(_clickHandler,value)
}
remove
{
_clickHandler = (EventHanlder)Delegate.Remove(_clickhandler,value);
}
}
}
//Generated Script
Button.prototype =
{
_clickHandler:null,
add_click:function(value){
this._clickHandler = Delegate.combine(this._clickHandler,value);
}
remove_click:function(value)
{
this._clickHandler = Delegate.remove)(this._clickHandler,value);
}
}
public class Button
{
private Eventhandler _clickHandler;
public event Eventhandler click
{
add{
_clickHandler = (Eventhandler)Delegate.Combine(_clickHandler,value)
}
remove
{
_clickHandler = (EventHanlder)Delegate.Remove(_clickhandler,value);
}
}
}
//Generated Script
Button.prototype =
{
_clickHandler:null,
add_click:function(value){
this._clickHandler = Delegate.combine(this._clickHandler,value);
}
remove_click:function(value)
{
this._clickHandler = Delegate.remove)(this._clickHandler,value);
}
}
最后,一个delegate调用delegates引用次序是按照delegate实例顺序来调用的.如函数都是自动使用对象的实例所绑定的一个具体的delegate实例.
//C#
public class Button
{
protected virual void OnClick(eventArgs e)
{
if(_clickHandler !=null)
{
_clickHandler(this,e);
}
}
}
//generated script
Button.prototype =
{
onClick:function(e)
{
if(this._clickHandler)
{
this._clickHandler(this,e);
}
}
}
public class Button
{
protected virual void OnClick(eventArgs e)
{
if(_clickHandler !=null)
{
_clickHandler(this,e);
}
}
}
//generated script
Button.prototype =
{
onClick:function(e)
{
if(this._clickHandler)
{
this._clickHandler(this,e);
}
}
}
------------------
How are Enumerations Defined and Consumed?
Enumeration是模仿一个对象被命名成员与每一个Enumeration field通讯,这个类型系统在 sscorlib.js中提供一个定义enumeration的API来实现.还有enum值的转换成相应的字符传特征.
//C#
public enum Colors{red = 0,Green = 1,Blue = 2}
[Flags]
public enumOption{OptionA=1,OptionB=2,OptionC=4}
Colors c = Colors.Red;
Option o = Options.OptionA | Options.OptionB;
//Generated Script
var Colors = Type.createEnum(false,'Colors',{Red:0,Green:1,Blue:2});
var Options = Type.createEnum(true,'Option',OptionA:1,OptionB:2,OptionC:4);
var c = Colors.Red;
var o = Options.OptionA | Option.OptionB;
public enum Colors{red = 0,Green = 1,Blue = 2}
[Flags]
public enumOption{OptionA=1,OptionB=2,OptionC=4}
Colors c = Colors.Red;
Option o = Options.OptionA | Options.OptionB;
//Generated Script
var Colors = Type.createEnum(false,'Colors',{Red:0,Green:1,Blue:2});
var Options = Type.createEnum(true,'Option',OptionA:1,OptionB:2,OptionC:4);
var c = Colors.Red;
var o = Options.OptionA | Option.OptionB;
注意 在debug和non-minimized构建enumeration fields时使用明确的引用.可是如对保存Script的大小感兴趣,当最小成为流行时,编译器可以用一个numeric值取代field引用.因此,所有类型信息结合enumeration值就会失效,并且他们在运行时的类型都是integer或number类型.所以推荐
你不要重新得到运行时enumeration field 值的类型,例如下面的代码最小化变量.
var Colors = Type.createEnum(false,'Colors',{Red:0,Green:1,Blue:2});
var Options = Type.createEnum(true,'Option',{OptionA:1,OptionB:2,OptionC:4});
var c =0;
var o = 1 | 2;
var Options = Type.createEnum(true,'Option',{OptionA:1,OptionB:2,OptionC:4});
var c =0;
var o = 1 | 2;
How are Properties Declared and Accessed?
Indexers 被模型化为使用一个对get/set访问器方法就想Properties样,指定"item"名(与CLR匹配).这个index如你期望的那样,参数与参数之间通过访问器来访问.
//C#
namespace Demo
{
public class Set
{
public object this[string name]
{
get{};
set{};
}
}
}
set s;
s["abc"] = object1;
object o = s["abc"];
//Generated Script
Demo.Set = function()
{.}
Demo.Set.prototype =
{
get_item:function(name){}
set_item:function(name,value){.}
};
Demo.Set.createClass('Demo.Set');
var s;
s.set_item('abc',object1);
var o = s.get_item('item');
namespace Demo
{
public class Set
{
public object this[string name]
{
get{};
set{};
}
}
}
set s;
s["abc"] = object1;
object o = s["abc"];
//Generated Script
Demo.Set = function()
{.}
Demo.Set.prototype =
{
get_item:function(name){}
set_item:function(name,value){.}
};
Demo.Set.createClass('Demo.Set');
var s;
s.set_item('abc',object1);
var o = s.get_item('item');
How are Events Declared and Accessed?
Events的模型是一个对add/remove访问器方法.一个命名转换使用"add_"和"remove_"被放在你定义的一个访问器前面.
这个访问器能被明确定义,后他们被编译器为一个事件field自动产生.如下面:
//C#
public class Button
{
public event EventHanlder Click
{
add{}
remove{}
}
}
public class Timer
{
public event Event EventHandler Tick;
}
//Generated Script
Button.prototype =
{
add_Click:function(value){.},
remove_Click:function(value){.}
}
Timer.prototype =
{
__tick:null,
add_tick:function(value)
{
__tick = Delegate.combine(this.__tick,value);
}
remove_tick:function(value)
{
___tick = Delegate.remove(this.__tick,value);
}
}
public class Button
{
public event EventHanlder Click
{
add{}
remove{}
}
}
public class Timer
{
public event Event EventHandler Tick;
}
//Generated Script
Button.prototype =
{
add_Click:function(value){.},
remove_Click:function(value){.}
}
Timer.prototype =
{
__tick:null,
add_tick:function(value)
{
__tick = Delegate.combine(this.__tick,value);
}
remove_tick:function(value)
{
___tick = Delegate.remove(this.__tick,value);
}
}
How are Static Members Declared and Accessed?
Static members被定在取代Class(C#)后的Class Prototype的中.还有一个static方法,Script#允许你写一个static的构造器.
//C#
public class Application
{
private static Application Current;
static Application()
{
Current = new Application();
}
static Applcation GetCurrent()
{
return Current;
}
}
//Generated Script
Application = function()
{}
Application.prototype =
{
}
Application.createClass('Application');
/'Static Methods'/
Applcation.getCurrent = function()
{
return Application._Current;
}
/static Ctors run as the script file loads/
Applcation._current = new Application();
public class Application
{
private static Application Current;
static Application()
{
Current = new Application();
}
static Applcation GetCurrent()
{
return Current;
}
}
//Generated Script
Application = function()
{}
Application.prototype =
{
}
Application.createClass('Application');
/'Static Methods'/
Applcation.getCurrent = function()
{
return Application._Current;
}
/static Ctors run as the script file loads/
Applcation._current = new Application();
How is a foreach Statement Implemented
你使用foreach 为如Arrays,Dictionaries,和自定义类型实现相应的接口等去枚举(enumerate) IEnumerable对象,Script#模型对foreach声明有两中辨别:
(1)每一项将枚举为DictionaryEntry类型
(2)就是其他的通常的枚举.
//C#
int[] items;
Dictionary table;
foreach(int i in items)
{
//Consume i
}
foreach(DictionaryEntry entry in table)
{
//Consume entry, i.e. entry .key and entry.value
}
//Generated Script
var items;
var table;
var $var1 = items.getEnumertor();
while($var1.moveNext())
{
var i = $var1.get_current();
//Consume i
}
var $dict1 = table;
for(Var $key in $dict1 ){
var entry = {key:$key,value:$dict1[$key]};
//comsume entry,i.e entry.key and entry.value
}
int[] items;
Dictionary table;
foreach(int i in items)
{
//Consume i
}
foreach(DictionaryEntry entry in table)
{
//Consume entry, i.e. entry .key and entry.value
}
//Generated Script
var items;
var table;
var $var1 = items.getEnumertor();
while($var1.moveNext())
{
var i = $var1.get_current();
//Consume i
}
var $dict1 = table;
for(Var $key in $dict1 ){
var entry = {key:$key,value:$dict1[$key]};
//comsume entry,i.e entry.key and entry.value
}
------------------------------
你能构建你自己的支持enumeration的类,只要实现IEnumerable,就像C#一样
How are Anonymous Delegates Implemented
匿名的delegates被实现使用JavaScript Closures.一个Closur被一个继承outer函数的context的内嵌function.
匿名的delegates内static成员的上下文中已经没有类的成员变量,而在VS中匿名的delegates定义内一个实例成员是有访问的成员变量的.
//C#
public delegate void xyzDelegate(int i);
public class MyClass
{
private static int Globaldata = 0;
private int _data;
public static void StaticMethod(object o)
{
int localData = 0;
DostuffStatic(o,delegate(int i)
{
localData = i + MyClass.GlobalData;
});
}
private static void DoStuffStatic(object o,XyzDelegate d)
{
//Some code , including code that invokes the delegate passed in
}
public void InstanceMethod(object o)
{
int localData = 0;
DoStuffInstance(o,delegate(int i))
{
_data = localData + i + MyClass.GlobalData;
}
}
public void DoStuffInstance(objcet o,XyzDelegate d)
{
//some code,including code that invokes the delegate passed in
}
}
//Generated Script
MyClass = function()
{
}
MyClass.staticMethod = function(o)
{
var localData = 0;
MyClass.doStuffStatic(o, new Delegate(null, function(i) { localData = i + MyClass.GlobalData; }));
}
MyClass.doStuffStatic = function(o, d)
{ // Some code, including code that invokes the delegate passed in }
MyClass.prototype =
{
_data: 0,
instanceMethod: function(o)
{
var localData = 0;
doStuffInstance(o, new Delegate(this, function(i) { this._data = localData + i + MyClass.GlobalData; }));
},
doStuffInstance: function(o, d)
{ // Some code, including code that invokes the delegate passed in }
}
MyClass.createClass('MyClass')
MyClass.GlobalData = 0;
public delegate void xyzDelegate(int i);
public class MyClass
{
private static int Globaldata = 0;
private int _data;
public static void StaticMethod(object o)
{
int localData = 0;
DostuffStatic(o,delegate(int i)
{
localData = i + MyClass.GlobalData;
});
}
private static void DoStuffStatic(object o,XyzDelegate d)
{
//Some code , including code that invokes the delegate passed in
}
public void InstanceMethod(object o)
{
int localData = 0;
DoStuffInstance(o,delegate(int i))
{
_data = localData + i + MyClass.GlobalData;
}
}
public void DoStuffInstance(objcet o,XyzDelegate d)
{
//some code,including code that invokes the delegate passed in
}
}
//Generated Script
MyClass = function()
{
}
MyClass.staticMethod = function(o)
{
var localData = 0;
MyClass.doStuffStatic(o, new Delegate(null, function(i) { localData = i + MyClass.GlobalData; }));
}
MyClass.doStuffStatic = function(o, d)
{ // Some code, including code that invokes the delegate passed in }
MyClass.prototype =
{
_data: 0,
instanceMethod: function(o)
{
var localData = 0;
doStuffInstance(o, new Delegate(this, function(i) { this._data = localData + i + MyClass.GlobalData; }));
},
doStuffInstance: function(o, d)
{ // Some code, including code that invokes the delegate passed in }
}
MyClass.createClass('MyClass')
MyClass.GlobalData = 0;
这个事例是显示一个内嵌方法的产生, 使用的局部数据被outer function访问或者是一个经过script closure的范围.这个事例还显内嵌方法被包装得像一个匹配C#语法的delegate,并且为匿名方法为delegates声明(declared)了static和instance两个不同的方法.
还有就是我们可以使用VS上面的ClassView来查看如sscrolib.dll和ssf.Core里面的类的结构.(我想大家都知道哦)
上面提到的两个.dll文件里面我都看完哦..还在整理中..等准备好了..我就写文章上来..和大家分享..黑...
-----------------worksguo-----