2010-02-13 19 views
5

C# oyununda bir yardımcı hata ayıklama sınıfı yaptım. Özelliklerin izlenmesi ve izlenmesi için üzerinde çalışıyorum. Şöyle devam ediyor:Özellik izleme kodunu iyileştirin mi?

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); 
    } 
} 

Şimdi bir özellik izlemek için, benim oyunun FPS, ben

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

orada nasılsa daha basit bu kullanmak için yapmak için bir yol olmaz yapmalısınız demek? İdeal

Monitor.Watch(Game.FPS); 

yapabilmek istiyorum Ama biz, bunu nasıl yapacağını bilmiyoruz store pointers to value types C# beri. Belki kapaklar ve lambada ifadeler kullanıyor olabilir? Bunu daha önce önerdim ama nasıl yapacağımı bilmiyorum. Bunu düzeltmek için başka yollar var mı?

Teşekkür

Şahsen

cevap

5

, ne yapacağını girdi olarak bir Func<string> kabul edin ve "unmonitor" sınıfı için kullanılabilecek bir izleme kolu dönmek için Monitör sınıfını yeniden işleme olduğunu.

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

Bu şuna benzer olabilir:

o yaparak, yazabilir olurdu

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... 
    } 
} 
Sen kolu için bazı arabirim uygulamak gerekiyordu

- ama bu gerçekten bir şey olabilir, çünkü bu sadece bir abonelik iptaline izin vermek için bir karma tablo araması olarak kullanılan bir nesnedir. Sadece "Unwatch" un çalışmasına izin vermek için buna ihtiyacınız var, çünkü anonim olarak tanımlamak isteyeceğiniz delegeleri kaldırmanın bir yolunun olması gerekiyor (yukarıda yaptığım gibi).

1

Neden INotifyPropertyChanged arabirimini kullanmıyorsunuz ve yalnızca Monitor sınıfı içindeki olayları tetikliyorsunuz, bunun gibi bir şey ... nesneleriniz arabirimi uyguladığını varsayar ... ve nesnelerinizdeki her özellik bir 'PropertyChanged' olayını artırır. Değerleri belirten parametreler ... bu şekilde, listeden bir döngü oluşturmak yerine bir yangın ve unu çözme çözümü olacak ... 'Başlat' için 'RenderWindow' parametresi olarak kullanılan 'Monitor' öğesini çağırırsınız. Ayrıca ... 'Mülkiyet' sınıf hafifçe söz konusu nesneyi döndürmek için bir get erişimcisi içerecek şekilde tadil olduğu bu yardımcı olur

 
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); 
    } 
} 

Hope, Saygılarımızla, Tom dikkat edin.