1、C#中定义事件的方法 第一种:逐个定义事件 public class WorkEventArgs : EventArgs public class SomeClass protected void OnWork(WorkEventArgs e) Asp.Net Ajax事件的定义与第二种差不多 定义委托List Demo.MyClass = function() 在Asp.Net Ajax中toLocaleString, valueOf, hasOwnProperty等方法都无法继承。通过重写Type的resolveInheritance方法解决 <script language=”javascript” type=”text/javascript”> if (this.__basePrototypePending) baseType.resolveInheritance(); for (var memberName in baseType.prototype) { Demo.Parent = function() 3、修改已有类型 添加某个类的成员直接可以在他的prototype上添加方法
\n
\n
{
/**//* */
}
\n
{
public event EventHandler<WorkEventArgs> Work;
protected void OnWork(WorkEventArgs e)
{
if (Work != null) Work(this, e);
}
}这是逐个定义事件的方式,其中EventHandler是也委托的范型,用来规定事件第二个参数的类型。这种方式在事件非常多的时候,会为每个事件生成一个委托对象。在事件没有使用到的情况下,会浪费内存。
第二种:事件集合的方式 public class SomeClass
{
static readonly object workEventKey = new object();
protected EventHandlerList eventDelegates = new EventHandlerList();
public event EventHandler<WorkEventArgs> Work
{
add
{
this.eventDelegates.AddHandler(workEventKey, value);
}
remove
{
this.eventDelegates.RemoveHandler(workEventKey, value);
}
}
\n
{
EventHandler<WorkEventArgs> workEventDelegates =
(EventHandler<WorkEventArgs>)this.eventDelegates[workEventKey];
if (workEventDelegates != null) workEventDelegates(this, e);
}
//…
}在这个示例里用实例化了一个委托的列表,用workEventKey 作为事件的标识符。使用这种方法,使用一个事件才会在委托列表中加入一个委托,这样可以有效的节约内存。如果要添加一个事件,那么必须添加一个object对象作为标识符
2、Asp.Net Ajax里面的事件
\n
\n
{
this._events = new Sys.EventHandlerList();
// …
}使用Sys.EnentHandlerList来实例化委托列表。
定义事件的add和remove Demo.MyClass.prototype=
{
add_myEvent : function(handler)
{
this._events.addHandler(“myEvent”, handler);
},
remove_myEvent : function(handler)
{
this._events.removeHandler(“myEvent”, handler);
},
//
} 这里用字符串代替object作为委托的key
添加触发事件的方法 Demo.MyClass.prototype =
{
raiseMyEvent : function(e)
{
var handler = this._events.getHandler(“myEvent”);
if (handler)
{
handler(this, e);
}
}
}通过使用委托(事件)列表的getHandler方法得到这个事件的委托,然后抛出这个事件。注意,要抛出空参数可以使用Sys.EventArgs.Empty来表示e为一个空参数
3、继承时需要注意的问题
\n
\n
//重写TyperesolveInheritance方法,就是解决继承的方法
Type.prototype.resolveInheritance = function TyperesolveInheritance()
{
if (arguments.length !== 0) throw Error.parameterCount();
\n
{
var baseType = this.__baseType;
\n
\n
var memberValue = baseType.prototype[memberName];
if (!this.prototype[memberName]) {
this.prototype[memberName] = memberValue;
}
}
//定义一个不能继承方法的方法名的数组
var dontEnumMembers = ["toString", "toLocaleString",
"valueOf", "hasOwnProperty", "isPrototypeOf",
"propertyIsEnumerable"];
//遍历这个数组
for (var i = 0; i < dontEnumMembers.length; i++)
{
var memberName = dontEnumMembers[i];
//如果这个类的这个方法已经定义,就不用理会
if (this.prototype[memberName] != Object.prototype[memberName])
{
continue;
}
//如果这个类的这个方法没有定义,得到基类这个方法的值
var memberValue = baseType.prototype[memberName];
//如果memberValue存在,就是基类的方法存在,并且不等于所有类的基类Object的
//的这个方法
if (memberValue != Object.prototype[memberName])
{
//将基类的这个方法付给子类,那么子类就继承了基类的这个方法
this.prototype[memberName] = memberValue;
}
}
delete this.__basePrototypePending;
}
}
</script>
不要在基类的构造函数中写toString方法
\n
{
// Incorrect
this.toString = function()
{
return Object.getTypeName(this);
}
}
这样做为什么不行,因为你在派生类定义一个toString方法是无法覆盖基类的toString的方法的,这违背了继承的原则。
\n
\n
修改某个成员需要先备份修改等方法,然后定义同名方法 var p = Demo.Employee.prototype;
p._old_calculateSalary = p._calculateSalary;
p._calculateSalary = function()
{
return this._old_calculateSalary() + (this.get_year() – 1) * 2000;
}这样做的缺点是修改基类的方法无法影响子类的方法。