Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 改进物业监控代码?_C#_Reflection_Properties_Closures - Fatal编程技术网

C# 改进物业监控代码?

C# 改进物业监控代码?,c#,reflection,properties,closures,C#,Reflection,Properties,Closures,我在一个C#游戏中创建了一个实用调试类,可以监视和监视属性值。是这样的: public static class Monitor { private static List<object> monitoredObjects; public static void Initialize() { monitoredObjects = new List<object>(); } public static void Watch(object o)

我在一个C#游戏中创建了一个实用调试类,可以监视和监视属性值。是这样的:

public static class Monitor
{
  private static List<object> monitoredObjects;

  public static void Initialize()
  {
   monitoredObjects = new List<object>();

  }

  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);
  }
 }
难道没有一种方法可以让它更简单地使用吗?理想情况下,我希望能够

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<IMonitorHandle, Func<string>> monitoredObjects;

    public static void Initialize()
    {
        monitoredObjects = new Dictionary<IMonitorHandle, Func<string>>();
    }

    public static IMonitorHandle Watch(Func<string> 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...
    }
}
公共静态类监视器
{
私有静态字典监视对象;
公共静态void Initialize()
{
monitoredObjects=新字典();
}
公共静态IMonitorHandle手表(Func o)
{
变量句柄=新监视器句柄(o);
monitoredObjects.Add(句柄,o);
返回手柄;
}
public static void Unwatch(IMonitorHandle)
{
监控对象。移除(手柄);
}
公共静态空白绘制(RenderWindow应用程序)
{
//不是真正的代码,我在游戏中画的
foreach(monitoredObjects.Values中的对象o)
Console.WriteLine(o());//执行以获取值。。。
}
}
您需要为句柄实现一些接口,但这实际上可以是任何接口,因为它只是一个用作哈希表查找的对象,用于允许取消订阅。您只需使用此选项即可允许“Unwatch”工作,因为您需要某种方法来删除委托,您可能希望匿名定义委托(如上所述)。

为什么不使用接口,而只是在Monitor类中触发事件,类似这样的事情…假设您的对象实现了接口…并且您对象中的每个属性都会引发一个“PropertyChanged”事件,其中的参数表示值…这样,它将是一个触发并忘记解决方案,而不是在列表中循环。。。当您调用实例化“监视器”时,将“RenderWindow”用作“初始化”的参数。还请注意,“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(object o) { monitoredObjects.Add(o); o.PropertyChanged += new EventHandler(monitor_PropertyChanged); } public static void Unwatch(object o) { o.PropertyChanged -= new EventHandler(monitor_PropertyChanged); monitoredObjects.Remove(o); } public static monitor_PropertyChanged(object sender, PropertyChangedEventArgs e){ // Not actual code, I actually draw this in game Console.WriteLine(e.SomeValue); } 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 object PropObj{ get{ return this.obj; } } 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); } } 公共静态类监视器 { 私有静态列表监视对象; 私有静态RenderWindow应用程序; 公共静态无效初始化(RenderWindow应用程序) { monitoredObjects=新列表(); } 公共静态无效监视(对象o) { 监测对象。添加(o); o、 PropertyChanged+=新事件处理程序(monitor_PropertyChanged); } 公共静态void Unwatch(对象o) { o、 PropertyChanged-=新事件处理程序(monitor_PropertyChanged); 监控对象。移除(o); } 公共静态监视器\u PropertyChanged(对象发送方,PropertyChangedEventArgs e){ //不是真正的代码,我在游戏中画的 Console.WriteLine(如SomeValue); } 公共静态空白绘制(RenderWindow应用程序) { //不是真正的代码,我在游戏中画的 foreach(监视器对象中的对象o) Console.WriteLine(o.ToString()); } } 公共类财产 { 私有对象对象; 私有财产信息财产信息; 公共对象专有{ 获取{返回this.obj;} } 公共重写字符串ToString() { 返回propertyInfo.Name+“:”+propertyInfo.GetValue(obj,null.ToString(); } 公共属性(对象o、字符串属性) { obj=o; propertyInfo=o.GetType().GetProperty(属性); } } 希望这有帮助, 顺致敬意, 汤姆

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(object o) { monitoredObjects.Add(o); o.PropertyChanged += new EventHandler(monitor_PropertyChanged); } public static void Unwatch(object o) { o.PropertyChanged -= new EventHandler(monitor_PropertyChanged); monitoredObjects.Remove(o); } public static monitor_PropertyChanged(object sender, PropertyChangedEventArgs e){ // Not actual code, I actually draw this in game Console.WriteLine(e.SomeValue); } 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 object PropObj{ get{ return this.obj; } } 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); } }