在C#中从外部监听对象更改

时间:2014-08-19 12:45:40

标签: c#

我有一个对象,我希望在数据发生变化时进行监控。但是我不允许向对象添加其他事件或接口,例如INotifyPropertyChanged,因此我需要从外部纯粹观察它,看看它是否已经改变了角色并通过它的所有属性来识别它的内容改变。

所以我基本上需要一个FileSystemWatcher,但对于一个对象。

C#是否提供我在这里寻找的任何功能?

2 个答案:

答案 0 :(得分:1)

你必须强制它并做一些事情,比如捕获对象的状态,然后在你需要检测变化时寻找差异(通过定期轮询或在你需要知道的特定点差别)。

我相信,这是监控数据模型对象变化的许多系统(例如RavenDB)。

我制作了一个快速而又脏的控制台应用程序,大致可以满足您的需求。它应该足以给你一个想法,但如果你想在生产代码中使用它,将需要一个完整的工作。 :)

class Program
{
    static void Main(string[] args)
    {
        DemoClass demo = new DemoClass { IntValue = 1, StringValue = "asdf" };

        var watcher = new DemoClassWatcher();
        watcher.Capture(demo);

        demo.StringValue = "1234";
        var results = watcher.Compare(demo); // results = "StringValue"
        demo.IntValue = 1234;
        results = watcher.Compare(demo); // results = "StringValue", "IntValue"
        watcher.Capture(demo);
        results = watcher.Compare(demo); // results = empty
    }
}

public class DemoClass
{
    public string StringValue { get; set; }
    public int IntValue { get; set; }
}

public class DemoClassWatcher
{
    private DemoClass lastRecorded = null;

    public void Capture(DemoClass objectToWatch)
    {
        lastRecorded = new DemoClass()
        {
            IntValue = objectToWatch.IntValue,
            StringValue = objectToWatch.StringValue
        };
    }

    public List<string> Compare(DemoClass currentObject)
    {
        var changes = new List<string>();
        var props = typeof(DemoClass).GetProperties(BindingFlags.Public | BindingFlags.Instance);
        foreach (var propertyInfo in props)
        {
            var currentVal = propertyInfo.GetValue(currentObject);
            var prevVal = propertyInfo.GetValue(lastRecorded);
            if (currentVal is IComparable)
            {
                if ((currentVal as IComparable).CompareTo(prevVal) != 0)
                    changes.Add(propertyInfo.Name);
                continue;
            }

            throw new NotSupportedException("Properties must support IComparable until someone fixes me up");
        }
        return changes;
    } 
}

答案 1 :(得分:0)

您无法监听不存在的事件,但您可以轮询状态并将其与之前的状态进行比较。

伪代码:

///initial config: 
yourObject = getAReferenceToTheObject();
previousState = new ObjectClass(yourObject);

///somewhere in a thread/loop
if (previousState.SomeProperty!= yourObject.SomeProperty){
    //state changed for SomeProperty on yourObject
}
//TODO: check other properties
previousState = new ObjectClass(yourObject); //implement copy constructor