Pergunta

Estou me preparando para criar uma classe EventArgs genérica para argumentos de eventos que carregam um único argumento:

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

Antes de fazer isso, o C# tem o mesmo recurso integrado à linguagem?Parece que me lembro de ter encontrado algo assim quando o C # 2.0 foi lançado, mas agora não consigo encontrar.

Ou, dito de outra forma, preciso criar minha própria classe EventArgs genérica ou o C# fornece uma?Obrigado pela ajuda.

Foi útil?

Solução

Não.Você provavelmente estava pensando em EventHandler<T>, que permite definir o delegado para qualquer tipo específico de EventArgs.

Eu pessoalmente não sinto isso EventArgs<T> é um ajuste tão bom, no entanto.As informações usadas como "carga útil" nos argumentos do evento devem ser, na minha opinião, uma classe customizada para deixar bem claro seu uso e propriedades esperadas.Usar uma classe genérica impedirá que você consiga colocar nomes significativos em seus lugares.(O que "Dados" representa?)

Outras dicas

Devo dizer que não entendo todos os “puristas” aqui.ou sejase você já possui uma classe de bolsa definida - que possui todas as especificações, propriedades etc.- por que o hack cria uma classe extra desnecessária apenas para poder seguir o mecanismo event/args, estilo de assinatura?a coisa é - nem tudo o que está no .NET - ou está 'faltando' - é 'bom' - a MS vem se 'corrigindo' há anos ...Eu diria que basta criar um - como eu fiz - porque eu precisava dele assim mesmo - e me economizou muito tempo,

Isso existe.Pelo menos, acontece agora.

Você pode encontrar DataEventArgs<TData> em alguns assemblies/namespaces diferentes da Microsoft, por exemplo Microsoft.Práticas.Prism.Eventos.No entanto, esses são namespaces que você pode não achar natural incluir em seu projeto, então você pode usar sua própria implementação.

Caso você opte por não usar Prisma, mas ainda gostaria de experimentar um genérico EventArgs abordagem.

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

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

// Use o seguinte código de exemplo para declarar ObjAdicionado evento

public event EventHandler<GenericEventArgs<TargetObjType>> ObjAdded;

// Use o seguinte código de exemplo para gerar ObjAdicionado evento

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

// E finalmente você pode assinar seu ObjAdicionado evento

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

NÃO HÁ ARGS GENÉRICOS INCORPORADOS.Se você seguir o padrão Microsoft EventHandler, implementará seus EventArgs derivados como sugerido:public class MyStringChangedEventArgs : EventArgs { public string OldValue { get; set; } }.

NO ENTANTO - se o guia de estilo da sua equipe aceitar uma simplificação - seu projeto pode usar eventos leves, como este:

public event Action<object, string> MyStringChanged;

uso:

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

Normalmente, os projetos de PoC usam a última abordagem.Em aplicações profissionais, entretanto, esteja ciente da justificativa do policial FX #CA1009: https://msdn.microsoft.com/en-us/library/ms182133.aspx

O problema com um tipo genérico é que mesmo que DerivedType herde de BaseType, EventArgs(DerivedType) não herdaria de EventArgs(BaseType).O uso de EventArgs(BaseType) evitaria, portanto, o uso posterior de uma versão derivada do tipo.

A razão pela qual isso não existe é porque o que acabaria acontecendo é que você implementa isso e, quando for preencher o T, deverá criar uma classe com propriedades inequívocas fortemente tipadas que atue como o pacote de dados para o seu argumento de evento, mas no meio da implementação, você percebe que não há razão para não fazer essa classe herdar de EventArgs e chamá-la de boa.

A menos que você queira apenas uma string ou algo similarmente básico para o seu pacote de dados, nesse caso provavelmente existem classes EventArgs padrão no .NET que se destinam a servir a qualquer propósito simples que você esteja alcançando.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top