2010-02-13 20 views
5

मैंने एक सी # गेम में उपयोगिता डीबग क्लास बनाया है, मैं गुणों के मूल्यों की निगरानी और निगरानी करने में सक्षम होने के लिए काम कर रहा हूं। इस प्रकार है: आदेश में एक संपत्ति की निगरानी के लिए मेंसंपत्ति निगरानी कोड में सुधार करें?

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(new Property(Game, "FPS")); 

वहाँ एक रास्ता किसी भी तरह इस सरल उपयोग करने के लिए बनाने के लिए नहीं होना चाहेंगे? आदर्श रूप में मैं

Monitor.Watch(Game.FPS); 

ऐसा करने में सक्षम होना चाहते हैं लेकिन चूंकि हम सी # में store pointers to value types नहीं, मुझे लगता है मैं यह कैसे करना होगा पता नहीं है सकते हैं। शायद बंद करने और lambada अभिव्यक्तियों का उपयोग कर? मुझे पहले यह सुझाव दिया गया था लेकिन मुझे यकीन नहीं है कि यह कैसे करें। इसे सुधारने के किसी भी अन्य तरीके?

धन्यवाद

उत्तर

5

व्यक्तिगत रूप से, मैं क्या होगा एक Func<string> इनपुट के रूप में स्वीकार करते हैं, और एक निगरानी संभाल कि "unmonitor" वर्ग के लिए इस्तेमाल किया जा सकता वापस जाने के लिए अपने मॉनिटर वर्ग rework है।

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... 
    } 
} 

आप को संभाल के लिए कुछ इंटरफ़ेस को लागू करना होगा - लेकिन इस वास्तव में कुछ भी हो सकता है, क्योंकि यह केवल एक ऑब्जेक्ट है जिसे सदस्यता के लिए हैश टेबल लुकअप के रूप में उपयोग किया जाता है। आपको केवल "अनवॉच" को काम करने की अनुमति देने की आवश्यकता है, क्योंकि आपको प्रतिनिधि को हटाने का कोई तरीका होना चाहिए, जिसे आप शायद अनामित रूप से परिभाषित करना चाहते हैं (जैसा मैंने ऊपर किया था)।

1

आप INotifyPropertyChanged इंटरफ़ेस का उपयोग क्यों नहीं कर रहे हैं और मॉनिटर क्लास के भीतर घटनाओं को केवल आग लगाना चाहते हैं ... मान लें कि आपकी ऑब्जेक्ट्स इंटरफ़ेस को लागू करती हैं ... और आपकी ऑब्जेक्ट्स में प्रत्येक प्रॉपर्टी 'PropertyChanged' ईवेंट को बढ़ाती है मानकों को इंगित करने वाले पैरामीटर ... इस तरह, यह सूची के माध्यम से लूपिंग के बजाय एक आग होगी और समाधान भूल जाएगी ... क्योंकि आप 'प्रारंभ' करने के लिए पैरामीटर के रूप में उपयोग किए जाने वाले 'रेंडरविंडो' के साथ तत्काल 'मॉनिटर' कहते हैं। यह भी ध्यान दें कि 'संपत्ति' वर्ग थोड़ा प्रश्न में वस्तु वापस जाने के लिए एक प्राप्त एक्सेसर शामिल करने के लिए संशोधित किया गया है ...

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

आशा इस मदद करता है, सादर, टॉम।

संबंधित मुद्दे