C# 改进物业监控代码?
我在一个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)
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);
}
}