Добрый день, я новичок в программировании, поэтому заранее прошу прощение за возможно глупый вопрос. Недавно столкнулся с такой проблемой, имеется объект некоторого класса какой вызывает некоторое событие. Так же имеется имеется другой объект содержащий первый объект как одну из своих переменных. Как в первом так и во втором объекте был реализован интерфейс ICloneable, в котором использовался метод Object.MemberwiseClone() для копирования множества свойств-значений. Так вот: при возникновении события в объекте клоне, метод обработчик вызывался первого объект-оригинала, а не объекта-клона (как ожидалось). Решение данной проблемы не нашел, пришлось отказаться от метода Object.MemberwiseClone() и вручную переназначать значения всех переменных новому объекту -клону. Вопрос в следующем: если кто-то сталкивался с подобным, может знает решение, как сделать чтобы обработчики события копировались а не ссылались на объект оригинал?? Вот сделал пример с подобной ситуацией:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Событие_и_клонирование
{
class Program
{
// Объявить тип делегата для события.
delegate void MyEventHandler();
// Объявить класс, содержащий событие.
class MyEvent: ICloneable
{
public int number { get; set; } //Номер объекта
public string name { get; set; } //Имя объекта
public event MyEventHandler SomeEvent;
// Этот метод вызывается для запуска события.
public void OnSomeEvent()
{
if (SomeEvent != null)
SomeEvent();
}
public object Clone()
{
MyEvent newMyEvent = (MyEvent)this.MemberwiseClone(); //Метод для копирования объектов значений
newMyEvent.name = String.Copy(name);
return newMyEvent;
}
}
//Класс содержащий событие
class EventDemo: ICloneable
{
public MyEvent evt = new MyEvent();
public EventDemo()
{
evt.SomeEvent += Handler; //присваиваем обработчик события
}
// Обработчик события.
void Handler()
{
Console.WriteLine("Событие произошло в объекте: " + evt.name);
}
public object Clone()
{
EventDemo newEventDemo = (EventDemo)this.MemberwiseClone(); //Метод для копирования объектов значений
newEventDemo.evt = (MyEvent)evt.Clone(); //Клонируем вложенный объект
return newEventDemo;
}
}
static void Main(string[] args)
{
//первый вариант
ObservableCollection<EventDemo> Collect = new ObservableCollection<EventDemo>() { new EventDemo(), new EventDemo()};
Collect[0].evt.name = "Объект 1";
Collect[0].evt.number = 1;
Collect[1].evt.name = "Объект 2";
Collect[1].evt.number = 2;
Console.WriteLine("Первый объект коллекции: " + Collect[0].evt.name+" Номер объекта: "+ Collect[0].evt.number);
Console.WriteLine("Второй объект коллекции: " + Collect[1].evt.name + " Номер объекта: " + Collect[1].evt.number);
foreach (EventDemo col in Collect)
{
col.evt.OnSomeEvent();
}
//второй вариант
Collect = new ObservableCollection<EventDemo>() { new EventDemo(), (EventDemo)Collect[0].Clone() };
Collect[0].evt.name = "Объект 1";
Collect[0].evt.number = 1;
Collect[1].evt.name = "Объект 2";
Collect[1].evt.number = 2;
Console.WriteLine("Первый объект коллекции: " + Collect[0].evt.name + " Номер объекта: " + Collect[0].evt.number);
Console.WriteLine("Второй объект коллекции: " + Collect[1].evt.name + " Номер объекта: " + Collect[1].evt.number);
foreach (EventDemo col in Collect)
{
col.evt.OnSomeEvent();
}
Console.ReadLine();
}
}
}
Выдает следующий результат:
Первый объект коллекции: Объект 1 Номер объекта: 1
Второй объект коллекции: Объект 2 Номер объекта: 2
Событие произошло в объекте: Объект 1
Событие произошло в объекте: Объект 2
Первый объект коллекции: Объект 1 Номер объекта: 1
Второй объект коллекции: Объект 2 Номер объекта: 2
Событие произошло в объекте: Объект 1
Событие произошло в объекте: Объект 1
Как видите событие происходит не в объекте 2, а в объекте 1