2010-07-22 66 views
74

我準備創建攜帶一個參數事件參數的通用EventArgs類:.NET是否有內置的EventArgs <T>?

public class EventArg<T> : EventArgs 
{ 
    // Property variable 
    private readonly T p_EventData; 

    // Constructor 
    public EventArg(T data) 
    { 
     p_EventData = data; 
    } 

    // Property for EventArgs argument 
    public T Data 
    { 
     get { return p_EventData; } 
    } 
} 

我這樣做之前,C#有內置的語言相同的特徵?我似乎記得在C#2.0出來時碰到類似的東西,但現在我找不到它了。

或者換句話說,我是否必須創建自己的通用EventArgs類,或者C#提供了嗎?謝謝你的幫助。

+8

您可能已經看到'事件處理' – 2010-07-22 18:33:41

+1

你可能已經看到了'''EventArgs的'''在CAB /基於SCSF碼。這在CAB/SCSF應用程序中很常見。雖然它不是框架的一部分,但是*是* EventArgs 的實現。 – 2013-02-26 19:49:15

回答

61

不,您可能在考慮EventHandler<T>,它允許您爲任何特定類型的EventArgs定義委託。

雖然我個人覺得EventArgs<T>還不錯。在我看來,在事件參數中用作「有效載荷」的信息應該是一個自定義類,以使其用法和預期屬性非常清晰。使用泛型類將會阻止您將有意義的名稱放置到位。 (「數據」代表什麼?)

+39

在以數據爲中心的類MPI應用程序中,通常會看到EventArgs 用於數據處理,以便開發人員可以利用內置的類型安全的訂閱/註冊系統(.NET Events and Delegates)作爲創建EventArgs子類僅用於傳輸數據絕對沒有意義。如果您的意圖是傳輸數據,可以說定義一個EventArgs更有意義,您可以繼承子類以用於離散使用,而不考慮傳輸的數據。 TL:DR這個答案的第一部分是事實和準確的,第二部分是主觀/意見。 – 2013-02-26 19:31:28

+1

我想你是對的......抵制讓我在這裏的懶惰。這就像懶惰的開發者使用Tuple <,>。可怕的東西。 – CRice 2014-08-01 03:35:12

+0

這是一個很好的觀點,但這基本上與微軟在將標籤屬性添加到控件類時所做的相同。當然,只是因爲'MS做到了這一點,並不是正確的。 – 2014-11-20 19:23:57

-4

這個不存在的原因是因爲最終會發生的是你實現這個,然後當你去填充T時,你應該創建一個強類型明確的類這些屬性充當事件arg的數據包,但是在實現的過程中,您意識到沒有理由不讓這個類從EventArgs繼承並稱之爲好。

除非你只是想要一個字符串或類似於你的數據包的基本類型,在這種情況下,在.NET中可能存在EventArgs類標準,這些標準旨在爲你提供任何簡單的目的。

+0

-1。我現在完全是這樣,我的有效載荷將是一個不可改變的對象,這是一個來自公共汽車的「消息」......並且也在其他地方也是如此。自定義EventArgs ....在這裏創建一個冗餘類。不尋常的,但應用程序是如此。 – TomTom 2010-07-22 21:04:59

1

泛型類型的問題是,即使DerivedType繼承自BaseType,EventArgs(DerivedType)也不會從EventArgs(BaseType)繼承。因此使用EventArgs(BaseType)將會阻止稍後使用派生版本的類型。

+2

這顯然是錯誤的。請參閱「泛型中的協變和逆變 - Microsoft.com」http://msdn.microsoft.com/en-us/library/dd799517.aspx – 2013-02-26 19:33:31

+1

@ShaunWilson:什麼方面是錯誤的?人們可以定義一個協變接口'IEventArgs',但是對於泛型類型參數可以是通用的唯一類是不會被饋送給'Delegate.Combine'的委託。將與'Delegate.Combine'一起使用的代表不應該是協變的,因爲可以存儲例如一個'動作'到類型爲'Action '的字段中,但是稍後嘗試'組合'與'行動'的實例將失敗。 – supercat 2013-02-26 21:53:24

26

我必須說我不明白這裏的所有'純粹主義者'。 即,如果你已經定義了一個包類 - 它具有所有的細節,屬性等 - 爲什麼黑客創建一個額外的不必要的類,只是爲了能夠遵循事件/參數機制,簽名樣式?事實上 - 並非所有在.NET中的東西 - 或者從這個問題上'缺少' - 是'好' - MS多年來一直在'糾正'自己... 我想說的就是創建一個像我做了 - 因爲我需要它就像那樣 - 並且節省了我很多時間,

+2

在這種情況下,「純粹主義者」的觀點是儘可能使意圖清楚。在生產應用程序中,我有幾十個這樣的EventArgs類。一年後,如果我遵循Reed的建議並創建一個自定義EventArgs類,將會更容易理解我做了什麼。 – 2011-03-27 15:13:20

+8

並不意味着標記任何人:) 點在事件'通用' - 如果你只需要一打不同的事件,好的。但是如果你事先不知道T的本質 - 這隻在運行時才知道 - 那麼你需要一個通用事件。所以,如果你有一個應用程序是處理泛型的一個很好的部分,一個任意類型的未知數 - 那麼你也需要泛型事件。或者說,對於每一個問題都沒有簡潔的解決方案,經驗法則只是一個經驗法則 - 這就是純粹主義者的意思,每個解決方案都不同,你需要衡量事物的優點和缺點 – NSGaga 2011-04-08 10:37:14

7

它確實存在。至少,它現在。

您可以在某些不同的Microsoft程序集/命名空間中找到DataEventArgs<TData>,例如Microsoft.Practices.Prism.Events。然而,這些名稱空間在項目中可能不太自然,所以您可能只使用自己的實現。

+0

我一直在試圖找到有關何時以及爲什麼要使用這樣的通用EventArgs類的建議和考慮事項。另請參閱:http://stackoverflow.com/questions/15766219/ok-to-use-dataeventargstdata-instead-of-customized-event-data-class – 2013-04-09 08:22:18

+0

下面是決定使用通用EventArgs時需要注意的一些方面: http://stackoverflow.com/questions/129453/net-eventhandlers-generic-or-no/129613#129613 – 2013-10-03 14:23:42

6

如果您選擇不使用Prism,但仍想嘗試通用EventArgs的方法。

public class GenericEventArgs<T> : EventArgs 
{ 
    public T EventData { get; private set; } 

    public GenericEventArgs(T EventData) 
    { 
     this.EventData = EventData; 
    } 
} 

//使用下面的示例代碼來聲明ObjAdded事件

public event EventHandler<GenericEventArgs<TargetObjType>> ObjAdded; 

//使用下面的示例代碼,以提高ObjAdded事件

private void OnObjAdded(TargetObjType TargetObj) 
{ 
    if (ObjAdded!= null) 
    { 
     ObjAdded.Invoke(this, new GenericEventArgs<TargetObjType>(TargetObj)); 
    } 
} 

//而finnaly你可以訂閱你的ObjAdded事件

SubscriberObj.ObjAdded += (object sender, GenericEventArgs<TargetObjType> e) => 
{ 
    // Here you can explore your e.EventData properties 
}; 
3

沒有內置的一般ARGS。 如果您關注Microsoft EventHandler模​​式,那麼您可以按照您的建議實施派生的EventArgs: public class MyStringChangedEventArgs : EventArgs { public string OldValue { get; set; } }

無論其 - 如果你的團隊風格指南接受簡化 - 你的項目都可以使用一個輕量級的事件,就像這樣:

public event Action<object, string> MyStringChanged; 

用法:

// How to rise 
private void OnMyStringChanged(string e) 
{ 
    Action<object, string> handler = MyStringChanged; // thread safeness 
    if (handler != null) 
    { 
     handler(this, e); 
    } 
} 

// How to handle 
myObject.MyStringChanged += (sender, e) => Console.WriteLine(e); 

通常的PoC項目採用後一種方法。在專業領域應用,但是,要知道FX警察理由#CA1009的:https://msdn.microsoft.com/en-us/library/ms182133.aspx

相關問題