所以我试图创建自己的事件来初始化一个名为Car的类,它继承自Automobile对象。以下是C#代码中的相同内容:
`
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Abc.Training.Artifacts;
namespace Abc.Training.Objects
{
public abstract class Automobile
{
public string Model { get; set; }
public string Manufacturer { get; set; }
public string YoM { get; set; }
}
public class Car : Automobile
{
public static event Delegates.ObjectInitHandler OnInit;
public string MarketSegment { get; set; }
public int BootSpace { get; set; }
public Car(string model, string manufacturer, string yom)
{
Model = model ;
Manufacturer = manufacturer;
YoM = yom;
ObjectInitEventArgs eArgs = new ObjectInitEventArgs();
eArgs.IsResidentObject = true;
eArgs.ObjectType = this.GetType();
if (OnInit != null) OnInit(this, eArgs);
}
}
}
`
ObjectInitHandler及其args(此处使用的委托类型)也是由我创建的:
`
public delegate void ObjectInitHandler(object sender, ObjectInitEventArgs e);
public class ObjectInitEventArgs:EventArgs
{
public Type ObjectType { get; set; }
public bool IsResidentObject { get; set; }
}
`
我订阅了以下活动:
`
Car.OnInit += new Delegates.ObjectInitHandler(Car_OnInit);//able to do this as event is static
Car c = new Car("Maruti", "Maruti", "2004");
void Car_OnInit(object sender, ObjectInitEventArgs e)
{
Console.WriteLine("Car object initialized");
}
`
我想为这个类创建一个OnInit事件。但是,如果我在发布者(我的Car类)中放置一个实例事件OnInit,我必须首先初始化该类,然后才能订阅此事件。因为我想在初始化时触发这个事件,这对我来说就成了鸡蛋和鸡蛋的问题。
我通过创建一个静态事件Object并在对象初始化之前进行订阅来解决它,如下所示(这是上面代码中的代码片段):
public static event Delegates.ObjectInitHandler OnInit;
但是,在ASP.NET应用程序中,这意味着如果多个用户访问此应用程序,我将拥有相同的委托对象,它将具有重复的事件订阅(因为它的静态),这显然不是很酷。
我是否有一个设计模式可以让事件也作为实例成员但我仍然可以在实例化之前订阅该事件?
答案 0 :(得分:1)
我认为你必须将该函数作为回调传递:
public class Car : Automobile
{
// public static event Delegates.ObjectInitHandler OnInit; remove this
public string MarketSegment { get; set; }
public int BootSpace { get; set; }
public Car(string model, string manufacturer, string yom,ObjectInitHandler OnInit) //add the callback as parameter.
{
Model = model ;
Manufacturer = manufacturer;
YoM = yom;
ObjectInitEventArgs eArgs = new ObjectInitEventArgs();
eArgs.IsResidentObject = true;
eArgs.ObjectType = this.GetType();
if (OnInit != null) OnInit(this, eArgs);
}
}
初始化对象时,将回调传递给构造函数:
Car c = new Car("Maruti", "Maruti", "2004",new Delegates.ObjectInitHandler(Car_OnInit));
void Car_OnInit(object sender, ObjectInitEventArgs e)
{
Console.WriteLine("Car object initialized");
}
实际上,除非构造函数中有异步操作,否则我认为代码中不需要初始化事件。
答案 1 :(得分:1)
这是一种方法,它不使用静态,我使用Actions而不是事件参数。 (你可以按照自己的方式使用它!)
请注意,我在创建时将回调函数传递给对象!
class Program
{
static void Main(string[] args)
{
Car c = new Car("Maruti", "Maruti", "2004", Car_OnInit);
Console.WriteLine("Press a key to exit...");
Console.ReadKey();
}
static void Car_OnInit()
{
Console.WriteLine("Car object initialized");
}
}
public abstract class Automobile
{
public string Model { get; set; }
public string Manufacturer { get; set; }
public string YoM { get; set; }
}
public class Car : Automobile
{
public event Action OnInit;
public string MarketSegment { get; set; }
public int BootSpace { get; set; }
public Car(string model, string manufacturer, string yom, Action callBack)
{
this.OnInit += callBack;
Model = model;
Manufacturer = manufacturer;
YoM = yom;
if (OnInit != null) OnInit();
}
}
如果您愿意,也可以传递任何争论者,只需使用Action<T>
代替Action<string>
而不是动作。然后你的回调将是Car_OnInit(字符串)
答案 2 :(得分:0)
没有必要(即使有可能)。你有你需要的一切。
首先,您不会订阅每个页面加载/每个用户的事件。您可以在Application_Start
中执行一次..
第二..你拥有活动所需的一切。注意这行代码:
if (OnInit != null) OnInit(this, eArgs);
您将this
作为sender
参数传递。 this
是Car
的一个实例。所以,在你的活动中......你有你关心的实例:
void Car_OnInit(object sender, ObjectInitEventArgs e) {
var instance = sender as Car;
// use instance here.
}