Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Как отписаться от события

57K
13 ноября 2012 года
xWinDx
15 / / 24.05.2010
Доброе время суток!
В общем ситуация такая: есть три класса("Class1","Class2","Class3")...
"Class1" содержит публичное событие "Event1"
Структура "Class2":
Код:
class Class2
{
    private Class1 _fieldName;
    public Class1 FieldName
    {
            get { this._fieldName }
    }
    public Class2()
    {
      this._fieldName.Event1 += new System.EventHandler(method1);
    }
     private void method1(object sender, EventArgs e)
     {
     }
}
Структура "Class3":
 
Код:
class Class3 : Class2
{
    public Class3(): base()
    {
      // тут нужно отписаться
    }
 
}
Примичание: Доступа к редактированию классов 1 и 2 нету, также в классе 3 вызывать базовый конструктор обязательно...
Спасибо за помощь...
Писал по памяти, если есть вопросы спрашивайте!!!
Через reflection я нашёл MethodInfo нужного метода, я просто низнаю, что мне счас делат с этим MethodInfo, как отписать?!!!
40K
13 ноября 2012 года
D129
228 / / 18.04.2012
 
Код:
this._fieldName.Event1 -= method1;
57K
13 ноября 2012 года
xWinDx
15 / / 24.05.2010
Нет такой вариант не подходит))) я бы и сам так сделал))) Внимательнее вопрос прочитайте... method1 приватный, и прочтите примичание... Спс за отзыв!
40K
13 ноября 2012 года
D129
228 / / 18.04.2012
Цитата: xWinDx
Нет такой вариант не подходит))) я бы и сам так сделал))) Внимательнее вопрос прочитайте... method1 приватный, и прочтите примичание... Спс за отзыв!



сделай паблик метод, который отписывается.

40K
13 ноября 2012 года
D129
228 / / 18.04.2012
protected - будет виден только потомкам.
40K
13 ноября 2012 года
D129
228 / / 18.04.2012
конструктор базового класса с параметром.
57K
13 ноября 2012 года
xWinDx
15 / / 24.05.2010
Я конечно благодарен за помощь , но повторюсь читайте внимательнее " Доступа к редактированию классов 1 и 2 нету, также в классе 3 вызывать базовый конструктор обязательно...
Спасибо за помощь..."
40K
13 ноября 2012 года
D129
228 / / 18.04.2012
 
Код:
class Class3 : Class2
{
    public Class3(bool DisableEvent): base(DisableEvent)
    {
      // тут нужно отписаться
    }
 
}

Но вообще-то, эвент не для того, чтобы его обрабатывал приватный метод того же класса, где можно поднять эвент.
Излишне это - если вам надо что-то сделать внутри класса - так и делайте, вызывайте метод, поднимайте эвент - но для кого-то внешнего!
Может вам эвент вообще и не нужен.
57K
13 ноября 2012 года
xWinDx
15 / / 24.05.2010
Ладно, спасибо... но у меня именно такая ситуация... ВОПРОС ОТКРЫТ!
40K
13 ноября 2012 года
D129
228 / / 18.04.2012
счас посмотрю.
Вообще-то, это врядли. Эвенты и делегаты - самая кривая часть в дотнете, в смысле логики ООП.
40K
13 ноября 2012 года
D129
228 / / 18.04.2012
Цитата: xWinDx
Ладно, спасибо... но у меня именно такая ситуация... ВОПРОС ОТКРЫТ!



Рейтинг на сайте у вас такой - бывает, что и этого не знают.....
:-)

40K
13 ноября 2012 года
D129
228 / / 18.04.2012
нет, не дали такой возможности.

Если подставить фальшивый метод - то ничего не происходит,
Все остальные свойства делегата (чтобы сделать точно такой же, и чтобы -= смог его в списке обработчиков удалить) только для чтения.

Делегаты не приводятся один к другому, даже если их сигнатуры совпадают.

Отписаться от эвента может только тот, кто на него подписался.
57K
13 ноября 2012 года
xWinDx
15 / / 24.05.2010
Это откуда инфа?
40K
13 ноября 2012 года
D129
228 / / 18.04.2012
Ваше задание выполнено, достигнут полный провал:


Код:
static void Main(string[] args)
        {

            Atom ddd = new Atom();

           
           
        //  MethodInfo dddInfo = ddd.GetType().GetMethod ("ddd_TestEv");



        //  ddd.TestEv -= dddInfo.MethodHandle.GetFunctionPointer();


        //  MetodForRemove metodFromBase;

        //  metodFromBase.Method.MethodHandle = dddInfo.MethodHandle ;


            ddd.TestEv -= false_metod;

            ddd.RiseTestEvent();
           
        }
       

        static void false_metod(object sender, EventArgs e)
        {
            throw new NotImplementedException();
        }
40K
13 ноября 2012 года
D129
228 / / 18.04.2012
Цитата: xWinDx
Это откуда инфа?


Про проблему с делегатами у Троэлсена читал.

Они не поняли тогда, что это надо сделать.

40K
13 ноября 2012 года
D129
228 / / 18.04.2012
Вам нужен хотябы приватный метод, который будет отписываться, но в базовом классе - и дернуть его через рефлексию....
но это глупо - если уж, то пусть сделают открытый метод для выключения!

Еще можно метод- обработчик сделать открытым и виртуальным, а в потомке - переопределить, и не делать ничего.
Будет эквивалентно отмене.
Но все равно - если базовый класс подписывается на свой собственный эвент - значит ему это очень нужно.

Ну допустим, логгер, или авторизация какая. А вы ее подавить хотите? Угадал?

:-)
57K
13 ноября 2012 года
xWinDx
15 / / 24.05.2010
нет, задача у меня тривиальная и мне просто нужно переписать обработчик события под свой... и да, загвоздка в том что классы 1 и 2 не мои( ладно, спс буду пытаться, я уверен что такое возможно...
40K
13 ноября 2012 года
D129
228 / / 18.04.2012
Возможно. Это надо вытащить тела (текст) методов и классов, изменить их, создать динамическую сборку, и наследоваться уже от нее (? с помощью динамических типов, что ли.... ), а не от изначальной.

А что, внутренний обработчик мешает? может его можно просто игнорировать? Что такого он делает?
В общем случае - легче и быстрее переписать нужный функционал.
Или даже подписаться на этот же эвент и удалять последствия работы предыдущего обработчика - из разряда извращений.
57K
13 ноября 2012 года
xWinDx
15 / / 24.05.2010
Дело в том, что обработчик который необходима удалить, приводит нужную мне переменную к определённому типу(в Классе2), а в наследованном классе (Класс3, мой)... это переменная другого типа, вследствии чего возникает исключение
40K
13 ноября 2012 года
D129
228 / / 18.04.2012
Не нарушайте тип в своем классе.
используйте то, что есть.
А если не хватает точности или еще чего - то добавьте функционал, сделайте свою переменную нужного типа.
Когда надо ее отдать предкам - конвертируйте обратно.
40K
13 ноября 2012 года
D129
228 / / 18.04.2012
потом - если это класс - вы же можете отнаследоваться, и приведение потомка к предку никак не помешает. Данные не потеряются, предки будут видеть свои поля, а вы - свои.
57K
13 ноября 2012 года
xWinDx
15 / / 24.05.2010
В том то и дело, если я сделаю так, как вы описали выше, то вообще теряет смысл всего моего функционала... измение типа переменной и есть оснавная задача...
57K
13 ноября 2012 года
xWinDx
15 / / 24.05.2010
Цитата: xWinDx
В том то и дело, если я сделаю так, как вы описали выше, то вообще теряет смысл всего моего функционала... измение типа переменной и есть оснавная задача...


Это интерфейс

40K
13 ноября 2012 года
D129
228 / / 18.04.2012
Ну и классно. Раз в коде нет смысла - значит он не нужен!

:-)
А лучший код - это не написанный код!

:-)))

Серьезно, у вас с дизайном какой-то косяк.
Не представляю задачи, когда класс автомобиль отнаследовали и сделали Хондой, а потом базовый класс приводит Хонду к велосипеду, на основании наличия колес.

Опишите подробнее как у вас классы организованы.
57K
13 ноября 2012 года
xWinDx
15 / / 24.05.2010
В общем организация класса, как в первом посте, и никуда от этого не деться....
Я поковырялся и УВЕРЯЮ -- это сделать можно!!!
 
Код:
class Class3 : Class2
{
     public Class3(): base()
     {
       // тут нужно отписаться
    var methodInfo = baseType.GetMethod("adapter_Changed", BindingFlags.NonPublic |                     BindingFlags.Instance | BindingFlags.DeclaredOnly);
        var eventInfo = base.Adapter.GetType().GetEvent("Changed");
     }
 
}
Тут нужно както через эти две переменные и делегат, а вот как хз)))
57K
14 ноября 2012 года
xWinDx
15 / / 24.05.2010
В обшем проблема решена, если кому интересно могу скинуть решение!
40K
14 ноября 2012 года
D129
228 / / 18.04.2012
Цитата: xWinDx
В обшем проблема решена, если кому интересно могу скинуть решение!



ну конечно.

57K
14 ноября 2012 года
xWinDx
15 / / 24.05.2010
Всё достаточно бонально
var methodInfo = baseType.GetMethod("adapter_Changed", BindingFlags.NonPublic | BindingFlags.Instance);
base.Adapter.Changed -= Delegate.CreateDelegate(typeof(EventHandler), this, methodInfo) as EventHandler;

Знаете кого-то, кто может ответить? Поделитесь с ним ссылкой.

Ваш ответ

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог