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

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

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

Author24 — интернет-сервис помощи студентам
Помогите разобраться с событиями. Читал уроки, но так и не разобрался. Как создать событие, которое будет вызываться если одна из переменных класса равна 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
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
26.03.2014, 21:30
Ответы с готовыми решениями:

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

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

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

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

5
Эксперт .NET
4432 / 2092 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
26.03.2014, 23:32 2
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 3
что такое событие: это буквально любое событие, например переменная равна нулю или изменилось значение какого-то свойства. Событие размещается в экземпляре класса как поле экземпляра класса:
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  [ТС] 4
НеСказочник, а можно два вопроса?

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

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


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

Но это действительно тратит чуть больше ресурсов. Так что систему событий лучше тщательнее продумать и делать проверки на события в соответствующих методах. Например, если есть метод, изменяющий координаты объекта, то в нём, после основной работы, надо размещать проверки на необходимость генерации события и сам вызов событий.
2
27.03.2014, 20:08
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
27.03.2014, 20:08
Помогаю со студенческими работами здесь

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru