简体   繁体   中英

Attach to Property's setter

I haven't found similiar post so I'm asking this.
Let's say I defined somewhere an application wide available static Property (I mean it's not local) and in one class I would like to know when this property is being changed. Apart from aop (transparentproxy etc.) which I think doesn't suit me well here (and I can't add that to project anyway), what are the options here?

One solution I can think of, which is probably a very nasty one, is to use some event that would be executed in the setter and just attach it in the class(es) which needs that. Something like:

   public static event EventHandler CurrentNumberChanged= delegate {};
   public static int CurrentNumber
    {
        get
        {
            return currentNumber;
        }
        set
        {
            currentNumber = value;

            CurrentNumberChanged(null, EventArgs.Empty);
        }
    }

I know it's really unsafe to use such events ( read here ). And since I would use it in asp.net makes it even more ugly. Do you have any advices ?

You could use a variation on the Observer pattern to the same effect. Not sure what your threading requirements are, and I suspect this suffers from similar dereferencing problems as How to raise custom event from a Static Class (although would have to play with the code a bit more to bottom that out):

using System; using System.Collections.Generic;

namespace ClassLibrary1 { public class StaticObservable { private static int currentNumber;

    private static readonly List<IObserver> observers = new List<IObserver>();

    public static int CurrentNumber
    {
        get{return currentNumber;}
        set
        {
            currentNumber = value;
            foreach (var observer in observers)
            {
                observer.NotifyChange();
            }
        }
    }

    public static void Attach(IObserver observer)
    {
        observers.Add(observer);
    }

    public static void Detach(IObserver observer)
    {
        observers.Remove(observer);
    }
}

public interface IObserver
{
    void NotifyChange();
}

public class ObserverImpl : IObserver
{
    public void NotifyChange()
    {
        Console.Out.WriteLine("Number has changed");
    }
}


public class AppWrapper
{
    public static void Main (string[] args)
    {
        Console.ReadLine();

        var observerImpl1 = new ObserverImpl();
        var observerImpl2 = new ObserverImpl();

        StaticObservable.Attach(observerImpl1);
        StaticObservable.Attach(observerImpl2);

        StaticObservable.CurrentNumber = 1;

        Console.ReadLine();
    }
}

}

您刚才提到的答案是,如果您忘记取消订阅静态事件的实例,则此实例将永远存在。

EventHandler is a bit too much I think, why not just create some boolean flag with a setter in the class that needs to receive the message, and whenever CurrentNumber's setter is triggered, call the setter of that boolean flag.
I'd like to be a little more descriptive here, but the data is not sufficient to suggest actual code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM