改善财产监控代码?

我在C#游戏中制作了一个实用程序调试类,我正在努力监视和查看属性值。 是这样的:

public static class Monitor { private static List monitoredObjects; public static void Initialize() { monitoredObjects = new List(); } public static void Watch(object o) { monitoredObjects.Add(o); } public static void Unwatch(object o) { monitoredObjects.Remove(o); } public static void Draw(RenderWindow app) { //Not actual code, I actually draw this in game foreach (object o in monitoredObjects) Console.WriteLine(o.ToString()); } } public class Property { private object obj; private PropertyInfo propertyInfo; public override string ToString() { return propertyInfo.Name + ": " + propertyInfo.GetValue(obj, null).ToString(); } public Property(object o, string property) { obj = o; propertyInfo = o.GetType().GetProperty(property); } } 

现在为了监控一个房产,说我的游戏的FPS,我必须这样做

 Monitor.Watch(new Property(Game, "FPS")); 

难道不会有办法以某种方式使这个更简单使用? 理想情况下,我希望能够做到

 Monitor.Watch(Game.FPS); 

但是因为我们无法在C#中存储指向值类型的指针 ,所以我不知道如何做到这一点。 也许使用闭包和lambada表达式? 我之前曾建议这样做,但我不知道该怎么做。 还有其他方法可以改善吗?

谢谢

就个人而言,我要做的是重写您的Monitor类以接受Func作为输入,并返回一个可用于“取消监视”该类的监视句柄。

通过这样做,你可以写:

  var handle = Monitor.Watch( () => Game.FPS.ToString() ); // later Monitor.Unwatch(handle); 

这看起来像是这样的:

 public static class Monitor { private static Dictionary> monitoredObjects; public static void Initialize() { monitoredObjects = new Dictionary>(); } public static IMonitorHandle Watch(Func o) { var handle = new MonitorHandle(o); monitoredObjects.Add(handle, o); return handle; } public static void Unwatch(IMonitorHandle handle) { monitoredObjects.Remove(handle); } public static void Draw(RenderWindow app) { //Not actual code, I actually draw this in game foreach (object o in monitoredObjects.Values) Console.WriteLine(o()); // Execute to get value... } } 

你需要为句柄实现一些接口 – 但这确实可以是任何东西,因为它只是一个用作哈希表查找的对象,允许取消订阅。 你只需要这个就可以让“Unwatch”工作,因为你需要有一些方法来删除你可能想要匿名定义的委托(正如我上面所做的那样)。

你为什么不使用INotifyPropertyChanged接口,只是触发Monitor类中的事件,就像这样……假设你的对象实现了接口……对象中的每个属性都会引发一个’PropertyChanged’事件,其中的参数指示值…以这种方式,它将是一个解决方案,而不是循环遍历列表…当您调用实例化’Monitor’时,’RenderWindow’用作’Initialize’的参数。 另请注意,’Property’类稍作修改,以包含一个get访问器来返回有问题的对象…

 public static class Monitor
 {
   private static List monitoredObjects;
   private static RenderWindow _app;

   public static void Initialize(RenderWindow app)
   {
    monitoredObjects = new List();

   }

   public static void Watch(对象o)
   {
    monitoredObjects.Add(O);
    o.PropertyChanged + = new EventHandler(monitor_PropertyChanged);
   }

   public static void Unwatch(对象o)
   {
    o.PropertyChanged  -  = new EventHandler(monitor_PropertyChanged);
    monitoredObjects.Remove(O);
   }

   public static monitor_PropertyChanged(object sender,PropertyChangedEventArgs e){
     //不是真正的代码,我实际上在游戏中画这个
     Console.WriteLine(e.SomeValue);
   }

   public static void Draw(RenderWindow app)
   {
                     //不是真正的代码,我实际上在游戏中画这个
    foreach(被监视对象中的对象o)
     Console.WriteLine(o.ToString());
   }
  }

 公共类财产
  {
  私人对象;
  私人PropertyInfo propertyInfo;

  公共对象PropObj {
     得到{return this.obj;  }
   }

  公共覆盖字符串ToString()
   {
    return propertyInfo.Name +“:”+ propertyInfo.GetValue(obj,null).ToString();
   }

   public属性(对象o,字符串属性)
   {
    obj = o;
    propertyInfo = o.GetType()。GetProperty(property);
   }
  }

希望这会有所帮助,最好的问候,汤姆。