Классы EventArg, необходимые теперь, когда у нас есть дженерики

Вы должны передать свою структуру по ссылке (& amp; оператор)

#include 
#include 

typedef struct{
    char name[25];
    int roll;
    float marks;    
} Student;

void getInfo(Student *student);
void display(Student *student);

int main(int argc, char *argv[]) {
    Student student;
    getInfo( &student );
    display( &student );
    return 0;
}

void getInfo(Student *student){
    printf("Enter student's name:");
    scanf("%s", student->name);
    printf("Enter student's roll:");
    scanf("%d", &student->roll);
    printf("Enter student's grade:");
    scanf("%f", &student->marks);
}

void display(Student *student){
    printf("NAME: %s\n", student->name);
    printf("ROLL: %d\n", student->roll);
    printf("GRADE: %.2f\n", student->marks);
}

Демо: https://repl.it/repls/LowNonstopWeb

19
задан leora 22 November 2008 в 15:46
поделиться

3 ответа

Что Вы описываете, по существу кортежи , сгруппированные значения, используемые для конкретной цели. Они - полезная конструкция в функциональное программирование и поддержка тот стиль очень хорошо.

оборотная сторона - то, что их значения не называют, и они требуют, чтобы контекст был понят. 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;
}

Это было бы намного более ясно с EventArgs представление события:

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

Универсальный допускающий повторное использование EventArgs классы упрощают разработку механизма за счет выражения намерения.

37
ответ дан 30 November 2019 в 03:21
поделиться

Посмотрите статья Custom Generic EventArgs , написанная Matthew Cochran , в той статье он описывает, как развернуть ее еще больше с двумя и тремя участниками.

Используя универсальный EventArgs имеют их использование и конечно их неправильные употребления, поскольку информация о типе потеряна в процессе.

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;
3
ответ дан 30 November 2019 в 03:21
поделиться

Поскольку TcKs уже заявил: Используйте EventArgs<T>, если только необходимо передать одно значение, иначе произойти от EventArgs (или EventArgs<T>, независимо от того, что Вы хотите).

0
ответ дан 30 November 2019 в 03:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: