문제

제네릭을 사용하면 특정 파생 Eventarg 클래스를 만들 이유가 있습니까?

이제 일반 구현으로 단순히 즉시 사용할 수있는 것 같습니다.

내 예제를 모두 가서 Eventarg 클래스 (stringeventargs, myfooeventargs 등)를 제거해야합니다.

public class EventArgs<T> : EventArgs
{
    public EventArgs(T value)
    {
        m_value = value;
    }

    private T m_value;

    public T Value
    {
        get { return m_value; }
    }
}
도움이 되었습니까?

해결책

당신이 묘사하는 것은 본질적으로입니다 튜플, 특정 목적으로 사용되는 그룹화 된 값. 그것들은 유용한 구성입니다 기능적 프로그래밍 그리고 그 스타일을 아주 잘 지원합니다.

단점은 그들의 값이 명명되지 않았으며 컨텍스트를 이해해야한다는 것입니다. EventArgs 바로 그 본성에 의해 종종 관련 맥락에서 멀리 떨어져 있습니다. 따라서 튜플-esque EventArgs 소비자에게 매우 혼란 스러울 수 있습니다.

일부 부서가 완료되었음을 나타내는 이벤트가 있으며, 분자, 분모 및 결과를 제공한다고 가정 해 봅시다.

public event EventHandler<EventArgs<double, double, double>> Divided;

이벤트 핸들러에는 몇 가지 모호성이 있습니다.

private void OnDivided(object sender, EventArgs<double, double, double> e)
{
    // I have to just "know" this - it is a convention

    var numerator = e.Value1;
    var denominator = e.Value2;
    var result = e.Value3;
}

이것은 AN에서 훨씬 더 명확 할 것입니다 EventArgs 이벤트 대표 :

private void OnDivided(object sender, DividedEventArgs e)
{
    var numerator = e.Numerator;
    var denominator = e.Denominator;
    var result = e.Result;
}

일반적인 재사용 EventArgs 클래스는 의도를 표현하는 비용으로 메커니즘의 발전을 용이하게합니다.

다른 팁

를보세요 맞춤형 일반 Eventargs 기사가 작성한 기사 매튜 코크란,이 기사에서 그는 2 명과 3 명의 회원으로 더 확장하는 방법을 설명합니다.

일반적인 Eventarg를 사용하면 프로세스에서 유형 정보가 손실되므로 사용하고 오용이 있습니다.

public class City {...}

public delegate void FireNuclearMissile(object sender, EventArgs<City> args);
public event FireNuclearMissile FireNuclearMissileEvent;

public delegate void QueryPopulation(object sender, EventArgs<City> args);
public event QueryPopulation QueryPopulationEvent;

다음 예에서는 유형-안전하지만 조금 더 LOC입니다.

class City {...}

public class FireNuclearMissileEventArgs : EventArgs
{
    public FireNuclearMissileEventArgs(City city)
    {
        this.city = city;
    }

    private City city;

    public City City
    {
        get { return this.city; }
    }
}

public delegate void FireNuclearMissile(object sender, FireNuclearMissileEventArgs args);
public event FireNuclearMissile FireNuclearMissileEvent;

public class QueryPopulationEventArgs : EventArgs
{
    public QueryPopulationEventArgs(City city)
    {
        this.city = city;
    }

    private City city;

    public City City
    {
        get { return this.city; }
    }
}

public delegate void QueryPopulation(object sender, QueryPopulationEventArgs args);
public event QueryPopulation QueryPopulationEvent;

TCKS가 이미 말했듯이 : 사용 EventArgs<T> 하나의 값만 전달하면됩니다. 그렇지 않으면 EventArgs (또는 EventArgs<T>, 당신이 원하는 뭐든지).

튜플 스타일 이벤트가 유용하다고 생각합니다. 튜플과 마찬가지로, 그들은 오용 될 수 있지만, 나의 게으름은 나의주의 감각이 더 강한 것 같습니다. 다음을 구현했습니다.

public static class TupleEventArgs
{
    static public TupleEventArgs<T1> Create<T1>(T1 item1)
    {
        return new TupleEventArgs<T1>(item1);
    }

    static public TupleEventArgs<T1, T2> Create<T1, T2>(T1 item1, T2 item2)
    {
        return new TupleEventArgs<T1, T2>(item1, item2);
    }

    static public TupleEventArgs<T1, T2, T3> Create<T1, T2, T3>(T1 item1, T2 item2, T3 item3)
    {
        return new TupleEventArgs<T1, T2, T3>(item1, item2, item3);
    }
}

public class TupleEventArgs<T1> : EventArgs
{
    public T1 Item1;

    public TupleEventArgs(T1 item1)
    {
        Item1 = item1;
    }
}

public class TupleEventArgs<T1, T2> : EventArgs
{
    public T1 Item1;
    public T2 Item2;

    public TupleEventArgs(T1 item1, T2 item2)
    {
        Item1 = item1;
        Item2 = item2;
    }
}

public class TupleEventArgs<T1, T2, T3> : EventArgs
{
    public T1 Item1;
    public T2 Item2;
    public T3 Item3;

    public TupleEventArgs(T1 item1, T2 item2, T3 item3)
    {
        Item1 = item1;
        Item2 = item2;
        Item3 = item3;
    }
}

다음과 같이 사용할 수 있습니다 ( 이벤트 라이저 확장)

public event EventHandler<TupleEventArgs<string,string,string>> NewEvent;

NewEvent.Raise(this, TupleEventArgs.Create("1", "2", "3"));
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top