Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/9: Рейтинг темы: голосов - 9, средняя оценка - 4.67
1 / 1 / 0
Регистрация: 11.06.2012
Сообщений: 24

Нужно ли для события создавать отдельный класс?

26.03.2014, 21:30. Показов 1935. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Помогите разобраться с событиями. Читал уроки, но так и не разобрался. Как создать событие, которое будет вызываться если одна из переменных класса равна 0 (или любое другое на ваш выбор).

Особый интерес вызывают следующие вопросы:
1. когда нужно создавать делегаты и почему в данном примере он нужен или ненужен
2. нужно ли для события создавать отдельный класс (в примерах иногда так и делают)


C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 class Class1  
    {
        public double a; 
        public double b; 
        public double c;
    }
 
 class Program
    {    
        static void Main(string[] args)
        {
            Class C = new Class(); //экземпляр класса 
            C.a = 5.8;
            C.b = 10.2;
            C.c = 0.0;
}
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
26.03.2014, 21:30
Ответы с готовыми решениями:

Нужно ли создавать отдельный класс или все писать в одном?
Добрый день! Возник такой теоретический вопрос. Может даже глупый. Пишу чат, есть класс MainWindow и много методов, слотов. Есть методы...

Нужно ли для каждого JS создавать отдельный файл?
Задался вопросом: нужно ли хранить каждый отдельный JS в отдельном файле или же эффективней писать все JS в одном? Повлияет ли это на...

Нужно ли для каждой страницы index создавать отдельный файл html?
Добрый вечер! Давно интересует вопрос, нужно ли для каждой страницы index, создавать отдельный файл html?

5
Эксперт .NET
 Аватар для Casper-SC
4434 / 2094 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
26.03.2014, 23:32
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
using System;
 
namespace ConsoleApplication1
{
    public class Something
    {
        protected double _value;
 
        public Something(double @value)
        {
            _value = @value;
        }
 
        public event EventHandler<ValueEventArgs> ValueChanged;
 
        protected virtual void OnValueChanged(ValueEventArgs e)
        {
            EventHandler<ValueEventArgs> handler = ValueChanged;
            if (handler != null) handler(this, e);
        }
 
 
        public double Value
        {
            get { return _value; }
            set
            {
                double oldValue = _value;
                _value = value;
                OnValueChanged(new ValueEventArgs(oldValue, value));
            }
        }
    }
}
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
using System;
 
namespace ConsoleApplication1
{
    public class ValueEventArgs : EventArgs
    {
        public ValueEventArgs(double oldValue, double newValue)
        {
            OldValue = oldValue;
            NewValue = newValue;
        }
 
        public double OldValue { get; protected set; }
        public double NewValue { get; protected set; }
    }
}
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
using System;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Something something = new Something(10d);
            something.ValueChanged += Something_ValueChanged;
            something.Value = 5.8;
            something.Value = 45d;
            something.Value = 34.6;
 
            something.ValueChanged -= Something_ValueChanged;
            something.Value = 23d;
            something.Value = 16d;
            something.Value = 31.5;
 
            Console.ReadKey();
        }
 
        static void Something_ValueChanged(object sender, ValueEventArgs e)
        {
            var some = (Something)sender; //для наглядности
            Console.WriteLine("Старое значение класса {0} = {1},\t новое = {2}",
                some.GetType().Name, e.OldValue, e.NewValue);
        }
    }
}
Добавлено через 3 минуты
Цитата Сообщение от nikitos7 Посмотреть сообщение
1. когда нужно создавать делегаты и почему в данном примере он нужен или ненужен
Да особо и не нужно вообще их создавать. Есть Action, Action<T>... Action<T1, T2, T3, T4> и т.д. Есть EventHandler, есть EventHandler<T>, где T в нашем случае - это ValueEventArgs

Цитата Сообщение от nikitos7 Посмотреть сообщение
2. нужно ли для события создавать отдельный класс (в примерах иногда так и делают)
Для параметров события да (ValueEventArgs)
1
60 / 48 / 13
Регистрация: 12.11.2012
Сообщений: 373
Записей в блоге: 2
26.03.2014, 23:39
что такое событие: это буквально любое событие, например переменная равна нулю или изменилось значение какого-то свойства. Событие размещается в экземпляре класса как поле экземпляра класса:
C#
1
2
3
4
5
6
7
8
9
10
class Class1
{
    public double a;
    public double b;
    public double c;
 
 
 
    public event MyEventHandler MyEvent;    /// вот это наше событие
}
где MyEventHandler - любой тип-делегат, описанный, например так:
C#
1
delegate void MyEventHandler(object sender, MyEventArgs e);
MyEventArgs - либо класс EventArgs, в случае, если твоё событие не должно передавать дополнительной информации, например о новом значении переменной, либо класс унаследованный от него:
C#
1
2
3
4
5
6
7
8
9
class MyEventArgs : EventArgs
{
    public double NewValue { get; set; }
 
    public MyEventArgs(double NewValue)
    {
        this.NewValue = NewValue;
    }
}
Каждый раз, когда происходит событие класс, являющийся источником события, передаёт экземпляр класса EventArgs или его наследника, например MyEventArgs, всем, кто на это событие подписан. В экземпляре класса MyEventArgs могут быть любые поля и переменные, которые нужно сообщить вместе с событием, но лучше его сильно не нагружать, а то самому хуже будет.

С точки зрения класса, который является источником или генератором события, например Class1, событие event MyEventHandler MyEvent как метод, который можно вызвать:
C#
1
2
3
//....
MyEvent(this, new MyEventArgs(0));
//...
Первый параметр sender это объект, который является источником события, лучше всего всегда писать this. Второй параметр e экземпляр класса EventArgs или его наследника. Он нужен для того, что бы класс источник события мог передать тем, кто на это событие подписан, любую необходимую информацию.

С точки зрения других классов событие - это поле экземпляра класса, в котором хранится коллекция делегатов, указывающих на функции, которые нужно вызвать, при срабатывании события. Работает это примерно так:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Program
{
 
    static void Main(string[] args)
    {
        Class1 c1 = new Class1();          //экземпляр класса Class1 
        c1.MyEvent += c1_MyEvent;      //так мы подписываемся на событие. Это значит, что при срабатывании события
                                                     //конкретно в экземпляре c1 класса Class1 будет вызван метод  c1_MyEvent
    }
 
 
 
////к этому методу довольно простые требования: он должен соответствовать делегату MyEventHandler, то есть иметь
////тот же возвращаемый тип и такой же набор параметров. Имя метода может быть любым, c1_MyEvent я взял для 
////наглядности. static не обязательно, но в данном примере необходимо, так как   c1.MyEvent += c1_MyEvent мы
////выполняем в статическом методе Main.
    static void c1_MyEvent(object sender, MyEventArgs e) 
    {
        
    }
}
Вызов события осуществляется непосредственно из экземпляра класса, в котором оно описано, как метода этого класса.


В твоём примере весь код может выглядеть примерно так:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
class MyEventArgs : EventArgs
    {
        public double NewValue { get; set; }
 
        public MyEventArgs(double NewValue)
        {
            this.NewValue = NewValue;
        }
    }
 
    delegate void MyEventHandler(object sender, MyEventArgs e);
 
 
    class Class1
    {
        private double _a;    // переменную a я сделал private, что вне класса её можно было изменить только
// через свойство. 
                              // Так проще контролировать когда она изменяется а когда нет.
 
        public double a       //непосредственно свойство a
        {
            get                 // метод get вызывется когда а оказфвается в правай части выражения от знака равно.
            {
                return _a;
            }
            set                // set вызывается когда а встречается слева от знака равно, т.е. ты ему
// что-то присваеваешь.
            {
                _a = value;     // сохраняем новое значение а
                MyEvent(this, new MyEventArgs(a));  // вызываем событие, как метод MyEvent и все методы,
// кто на него подписан, будут вызваны по очереди. 
            }
        }
 
        public event MyEventHandler MyEvent;
    }
 
 
    class Program
    {
 
        static void Main(string[] args)
        {
            Class1 c1 = new Class1();
            c1.MyEvent += c1_MyEvent;
        }
 
        static void c1_MyEvent(object sender, MyEventArgs e)
        {
        }
    }
2
1 / 1 / 0
Регистрация: 11.06.2012
Сообщений: 24
27.03.2014, 19:10  [ТС]
НеСказочник, а можно два вопроса?

1 - зачем переменную а желать закрытой и создавать свойство ведь получается что мы просто усложняем программу
2 - куда вставить проверку что a>0
0
Эксперт .NET
 Аватар для Casper-SC
4434 / 2094 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
27.03.2014, 19:17
Цитата Сообщение от nikitos7 Посмотреть сообщение
1 - зачем переменную а желать закрытой и создавать свойство ведь получается что мы просто усложняем программу
Вообще в .NET на свойствах многое завязано. Биндинги, например, и другое. Ну и принципы ООП (инкапсуляция - сокрытие). В простом классе может и кажется, что усложняешь. А если у тебя какая-то логика прописана внутри класса, а ты взял снаружи и поменял поле как захотел, чем нарушил работу этого класса. Просто заранее нужно думать о таком повороте. Или ты никогда не поменяешь, а тот кто будет дописывать твой софт на работе возьмёт и поменяет, он же не знал, что ты там придумал.

Добавлено через 23 секунды
Или свойство, к примеру, можно сделать только для чтения снаружи.
2
60 / 48 / 13
Регистрация: 12.11.2012
Сообщений: 373
Записей в блоге: 2
27.03.2014, 20:08
Цитата Сообщение от nikitos7 Посмотреть сообщение
НеСказочник, а можно два вопроса?
1 - зачем переменную а желать закрытой и создавать свойство ведь получается что мы просто усложняем программу
2 - куда вставить проверку что a>0


Затем свойство и делается. Если изменять переменную можно только через свойство, то любое событие, связанное с этой переменной, можно безошибочно вызывать в свойстве и
Цитата Сообщение от nikitos7 Посмотреть сообщение
проверку что a>0
тоже можно размещать в свойстве. Тогда проверка будет производиться при каждом изменении значения переменной.

Но это действительно тратит чуть больше ресурсов. Так что систему событий лучше тщательнее продумать и делать проверки на события в соответствующих методах. Например, если есть метод, изменяющий координаты объекта, то в нём, после основной работы, надо размещать проверки на необходимость генерации события и сам вызов событий.
2
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
27.03.2014, 20:08
Помогаю со студенческими работами здесь

Вынесение обработчика события в отдельный класс
Возникает следующая проблема: у многих форм одно и то же событие обрабатывается одинаковым кодом, поэтому вынес обработчик в отдельный...

Нужно-ли создавать базовый класс?
Есть базовый класс: class A { public: int variable; // Методы доступа: void set(int v) { variable =...

Отдельный класс для вычислений
Привет всем! У меня есть Form1, в которую нужно вводить данные для вычисления функции. Метод, вычисляющий данную функцию находится в классе...

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

Отдельный класс для каждой задачи
Здравствуйте. Есть элемент управления, допустим Picturebox. На нем прорисовывает много разных групп. Группа (в данном...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
Установка Emscripten SDK (emsdk) и CMake на Windows для сборки C и C++ приложений в WebAssembly (Wasm)
8Observer8 30.01.2026
Чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. Система контроля версиями Git. . .
Подключение Box2D v3 к SDL3 для Android: физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
Влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru