2014-02-09 73 views
0

所以我試圖創建自己的事件來初始化一個名爲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,則必須先初始化該類,然後才能訂閱此事件。由於我想在初始化時觸發這個事件,這對我來說成了一個雞和雞蛋的問題。

我解決它通過創建靜態事件對象和執行對象的初始化前的訂閱,如下所示(這是從上方本身的代碼的片段):

public static event Delegates.ObjectInitHandler OnInit;

然而,在ASP .NET應用程序,這將意味着如果多個用戶訪問這個應用程序,我將擁有相同的委託對象,它將具有重複的事件訂閱(因爲它的靜態),這顯然不是很酷。

是否有一個設計模式,我可以遵循該事件也作爲實例成員,但我仍然可以在實例化之前訂閱該事件?

回答

1

這裏是一種方法來做到這一點,它不使用靜態,我用動作,而不是事件參數。 (你可以用你的方式!)
請注意,我創建時將回調函數傳遞給對象!

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(); 
    } 

} 

您也可以通過任何argumenst如果你願意,只需使用Action<T>Action<string>,而不是行動。那麼你的回調將是Car_OnInit(字符串)

+0

我假設你想在創建它之前爲你的實例添加多個事件處理程序!在這種情況下,您應該將您的回調集中到數組中(Action [] callBackArray),將它傳遞給您的新車,然後在構造函數中將所有回調添加到您的事件中。 這種方式在構造函數結束時,事件將調用所有先前分配的函數... – Shamim

0

沒有必要(即使有可能)。你有你需要的一切。

首先,你不會訂閱每個頁面加載/每個用戶的事件。你會做一次..例如在Application_Start

第二..你擁有一切你需要的事件。請注意,這行代碼:

if (OnInit != null) OnInit(this, eArgs); 

您傳遞this作爲sender參數。 thisCar的一個實例。所以,在你的活動中..你有你關心的實例:

void Car_OnInit(object sender, ObjectInitEventArgs e) { 
    var instance = sender as Car; 

    // use instance here. 
} 
+0

**首先,你不會訂閱事件每個頁面加載/每個用戶。** - 我當然會,作爲一個例子Page_Init事件做同樣的事情。汽車對象只是爲了演示,在初始化時我會需要許多對象。 –

1

我認爲你必須傳遞函數作爲回調:

Car c = new Car("Maruti", "Maruti", "2004",new Delegates.ObjectInitHandler(Car_OnInit)); 
void Car_OnInit(object sender, ObjectInitEventArgs e) 
{ 
    Console.WriteLine("Car object initialized"); 
} 

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); 
     } 

    } 

初始化對象時傳遞一個回調來構造

實際上,除非在構造函數中有異步操作,否則在代碼中看不到需要初始化事件。

+0

需要的是:例如 - 頁面中的Page_Init事件說謊週期 –

+0

@Gaurav Karwal:Page_Init是一種不同的情況。基類定義了這個並在派生類中重寫。 –