.NET'te yerleşik EventArgs <T> var mı?


85

Tek bir bağımsız değişken taşıyan olay bağımsız değişkenleri için genel bir EventArgs sınıfı oluşturmaya hazırlanıyorum:

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

Bunu yapmadan önce, C # dilde aynı özelliğe sahip mi? C # 2.0 çıktığında böyle bir şeyle karşılaştığımı hatırlıyorum, ama şimdi bulamıyorum.

Ya da başka bir deyişle, kendi genel EventArgs sınıfımı oluşturmalı mıyım yoksa C # bir sınıf sağlıyor mu? Yardımınız için teşekkürler.


9
Görmüş olabilirsinizEventhandler<T>
Henk Holterman

1
EventArgs<T>CAB / SCSF tabanlı kodda görmüş olabilirsiniz . CAB / SCSF uygulamalarında oldukça yaygındır. Çerçevenin bir parçası olmasa da , bir EventArgs <T> uygulaması vardır.
Shaun Wilson

Yanıtlar:


68

Hayır. Muhtemelen düşünüyordunuz EventHandler<T>, bu da herhangi bir belirli EventArgs türü için temsilci tanımlamanıza izin verir.

Şahsen bunun EventArgs<T>bir uyum olarak iyi olduğunu düşünmüyorum . Olay bağımsız değişkenlerinde bir "yük" olarak kullanılan bilgi, bence, kullanımını ve beklenen özelliklerini çok açık hale getirmek için özel bir sınıf olmalıdır. Genel bir sınıf kullanmak, anlamlı isimler koymanıza engel olacaktır. ("Veri" neyi temsil eder?)


52
Veri merkezli, MPI benzeri uygulamalarda, geliştiricilerin yerleşik, tür güvenli bir abonelik / kayıt sisteminden (.NET Olayları ve Temsilciler) yararlanabilmesi için veri işleme için EventArgs <T> 'nin yerinde görülmesi oldukça yaygındır. Verileri taşımak için EventArgs alt sınıfları oluşturmak kesinlikle mantıklı olmadığından. Amacınız verileri taşımaksa, muhtemelen bir EventArgs <T> tanımlamak daha mantıklıdır, taşınan verilere bakılmaksızın ayrı kullanımlar için alt sınıflandırma yapabilirsiniz. TL: DR Bu cevabın bu ilk kısmı gerçek ve doğru, ikinci kısmı sübjektif / fikir.
Shaun Wilson

1
Sanırım haklısın ... beni buraya getiren tembelliğe diren. Bu, tembel geliştiricilerin Tuple <,> kullanması gibi. Korkunç şeyler.
CRice

İyi bir nokta, ancak bu, temelde Microsoft'un Tag özelliğini Controls sınıflarına eklediklerinde yaptığı şeyi yapıyor olacaktı. Tabii ki, sadece MS yaptı, doğru yapmaz.
Ken Richards

1
İlk yorumcuya katılıyorum, bu cevabın ikinci yarısı yapıcı olmayan öznel bir görüş / kod-din. :(
BrainSlugs83

6
Nasıl yok EventHandler <Müşteri> veya EventHandler <Sipariş> daha azını bilgi aktarmak CustomerEventHandler veya OrderEventHandler ?
Quarkly

33

Buradaki tüm 'safçıları' anlamadığımı söylemeliyim. Örneğin, zaten tanımlanmış bir çanta sınıfınız varsa - tüm özellikleri, özellikleri vb. içerir - hack, neden sadece olay / argüman mekanizmasını, imza stilini izleyebilmek için fazladan bir gereksiz sınıf yaratır? mesele - .NET'te olan - veya bu konuda 'eksik' olan her şey değil - 'iyi' - MS yıllardır kendini 'düzeltir' ... Sadece git ve benim yaptığım gibi bir tane yarat derim - çünkü buna ihtiyacım vardı - ve bana çok zaman kazandırdı,


3
Bu durumda 'safçıların' amacı, niyeti olabildiğince açık hale getirmektir. Bir üretim uygulamasında, bu EventArgs sınıflarından düzinelerce var. Bundan bir yıl sonra, Reed'in tavsiyelerine uyup özel bir EventArgs sınıfı oluşturursam ne yaptığımı anlamak daha kolay olacak.
David Veeneman

9
kimseyi etiketlemek istemedim :) nokta olayda 'genel' - sadece bir düzine farklı olaya ihtiyacınız varsa, tamam. Ancak T'nin doğasını önceden bilmiyorsanız - bu sadece çalışma zamanında bilinir - pekala, genel bir olaya ihtiyacınız var demektir. Dolayısıyla, jeneriklerle ilgilenen iyi bir parçası olan, keyfi bir tür türü bilinmeyen bir uygulamanız varsa - o zaman genel olaylara da ihtiyacınız var. ya da yani, her sorun için temiz bir çözüm yoktur, genel kural sadece
pratik

2
Tasarım siyah ve beyaz değil, bu yüzden burada NSGaga ile aynı fikirdeyim. Bazen "hızlı ve kirli" uygundur. Dil, çoğu kullanım durumuna uyması için zengin özelliklere sahip olmalıdır. Neyin uygun olduğuna karar vermek geliştiriciye kalmalıdır. MS, dili sınırlandırarak "iyi" tasarımı en son denediğinde, .NET API'yi ciddi şekilde engelleyerek XAML kullanımını zorlamaya çalıştıklarında WPF idi ve bu korkunçtu.
Robear

9

Var. En azından şimdi öyle.

Sen bulabilirsiniz DataEventArgs<TData>örneği için, bazı farklı Microsoft montajları / ad alanlarında Microsoft.Practices.Prism.Events . Ancak bunlar, projenize dahil etmeyi doğal bulmayabileceğiniz ad alanlarıdır, bu nedenle yalnızca kendi uygulamanızı kullanabilirsiniz.


Böyle genel bir EventArgs sınıfının ne zaman ve neden kullanılacağına ilişkin öneriler ve değerlendirmeler bulmaya çalışıyorum. Ayrıca bkz .: stackoverflow.com/questions/15766219/…
Ulf Åkerstedt

Genel EventArgs kullanmaya karar verirken dikkat etmeniz gereken bazı hususlar şunlardır: stackoverflow.com/questions/129453/…
Ulf Åkerstedt

7

Prism'i kullanmamayı seçtiyseniz , ancak yine de genel bir EventArgs yaklaşımını denemek istiyorsanız .

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

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

// ObjAdded olayını bildirmek için aşağıdaki örnek kodu kullanın

public event EventHandler<GenericEventArgs<TargetObjType>> ObjAdded;

// ObjAdded etkinliğini artırmak için aşağıdaki örnek kodu kullanın

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

// Son olarak, ObjAdded etkinliğinize abone olabilirsiniz

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

3

DAHİLİ JENERİK ARGLAR YOKTUR. Microsoft EventHandler biçim kullanılıyorsa, önerilen gibi, o zaman türetilmiş EventArgs uygulamak: public class MyStringChangedEventArgs : EventArgs { public string OldValue { get; set; } }.

ANCAK - takım stil rehberiniz bir basitleştirmeyi kabul ederse - projeniz aşağıdaki gibi hafif olayları kullanabilir:

public event Action<object, string> MyStringChanged;

kullanım:

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

Genellikle bir PoC projeleri ikinci yaklaşımı kullanır. Ancak profesyonel uygulamalarda, FX kopyası gerekçesine dikkat edin # CA1009: https://msdn.microsoft.com/en-us/library/ms182133.aspx


1

Genel bir türle ilgili sorun, DerivedType BaseType'tan miras alsa bile, EventArgs'ın (DerivedType) EventArgs'dan (BaseType) miras almamasıdır. EventArgs (BaseType) kullanmak, daha sonra türün türetilmiş bir sürümünün kullanılmasını engeller.


2
Bu açıkça yanlıştır. lütfen "Jeneriklerde Kovaryans ve Kontravaryans - Microsoft.com" msdn.microsoft.com/en-us/library/dd799517.aspx
Shaun Wilson

1
@ShaunWilson: Hangi yönü yanlış? Bir ortak değişken arabirim tanımlanabilir IEventArgs, ancak genel tür parametrelerine göre genel olabilecek sınıflar, beslenmeyecek delegelerdir Delegate.Combine. Birlikte kullanılacak temsilciler Delegate.Combineortak değişken olmamalıdır, çünkü biri örneğin bir Action<DerivedType>tür alanına bir depolanabilir Action<BaseType>, ancak daha sonra Combinebir örneğiyle buna yönelik bir girişim Action<BaseType>başarısız olacaktır.
supercat

-4

Bunun var olmamasının nedeni, sonunda olan şeyin bunu uygulamanızdır ve daha sonra T'yi doldurmaya gittiğinizde, etkinliğiniz arg için veri çantası olarak işlev gören, güçlü bir şekilde yazılmış, belirsiz özelliklere sahip bir sınıf oluşturmanız gerekir, ancak Uygulamanın yarısında, bu sınıfı sadece EventArgs'dan miras aldırıp ona iyi dememeniz için hiçbir neden olmadığını fark ediyorsunuz.

Veri çantanız için sadece bir dizge veya benzer şekilde temel bir şey istemediğiniz sürece, bu durumda muhtemelen .NET'te standart EventArgs sınıfları vardır ve bu sınıflar, ulaştığınız basit amaca hizmet etmek içindir.


-1. Tam olarak şu anda bu durum uyarısına sahibim ve yüküm, bir otobüsten gelen bir "mesaj" olan değişmez bir nesne olacak ... ve başka yerlerde de bulunacak. Özel EventArgs .... burada yedekli bir sınıf oluşturur. Alışılmadık, ancak uygulama öyle.
TomTom
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.