2013-07-30 14 views
5

में मेरे माध्यम से बाल वर्ग गुणों तक पहुंचने से मेरा सीटीओ (मुख्य तकनीकी अधिकारी) ने मुझे एक ऐसे तरीके से आने के लिए कहा जहां वह बेस क्लास में एक एकल कार्य लिख सकता था, और सभी संपत्तियों तक पहुंच प्राप्त कर सकता था बाल वर्ग यहाँ मैं क्या लेकर आए हैं - फाइलअभिभावक वर्ग

बेस कक्षा

class Assets 
{ 
    public Assets getPropertyVal(Assets asObj) 
    { 
     PropertyInfo[] propInfos = asObj.GetType().GetProperties(); 
     string strAttributeValue = "10"; 
     foreach (PropertyInfo propInfo in propInfos) 
     { 
      // Getting the value 
      var propValue = propInfo.GetValue(asObj, null); 

      // Setting the value 
      propInfo.SetValue(asObj, Convert.ChangeType(strAttributeValue, propInfo.PropertyType), null); 

     } 
     return asObj; 
    } 
} 

बाल कक्षा

class House : Assets 
{ 
    public int rooms{get; set;} 
} 

Program.cs

class Program 
{ 
    static void Main(string[] args) 
    { 
     House hsObj = new House(); 
     hsObj.rooms = 5; 

     Assets asObj = hsObj.getPropertyVal(hsObj); 
     // Returns asObj as JSON 
    } 
} 

अब यह ठीक काम करता है, लेकिन मैं बस सोच रहा था कि सी # में ऐसा करने का बेहतर तरीका है या नहीं।

ध्यान दें कि हमें नहीं पता कि बाल वर्ग में कौन सी संपत्तियां मौजूद होंगी, इसलिए इसे रन-टाइम पर निर्धारित करना होगा।

अद्यतन: यह स्पष्ट, मैं सिर्फ अगर वहाँ प्रतिबिंब का उपयोग किए बिना बच्चे वर्ग गुण, एक का उपयोग करने के लिए एक बेहतर तरीका है सोच रहा था बनाना। ध्यान देने योग्य महत्वपूर्ण बात यह है कि हमें नहीं पता कि बाल वर्ग के गुण क्या हो सकते हैं।

अद्यतन # 2: मैं ऐसे उत्पाद के साथ काम कर रहा हूं जिसमें कई संस्थाएं हैं। इन इकाइयों के पास अलग-अलग गुण हैं। मैं इन सभी गुणों के साथ एक ही स्थान पर पहुंचने और काम करने में सक्षम होना चाहता हूं। यह कार्य ठीक है। यह वह जगह है जहां से मैं सभी डेटा तक पहुंच सकता हूं।

+1

अपने उदाहरण में, आप ऑब्जेक्ट बनाते हैं और ऑब्जेक्ट के सभी गुण प्राप्त करते हैं और फिर ऑब्जेक्ट में वही गुण सेट करते हैं। यह इस तरह दिखता है: 'var propValue = asObj.rooms; asObj.rooms = (int) propValue; '। तुम्हारी वास्तव में इच्छा क्या है? क्या आप एक बच्चे वर्ग से सभी वर्गों की मूल कक्षा में प्रतिलिपि बनाना चाहते हैं? –

+0

@ व्याचेस्लाववल्कोव, मैं बस सोच रहा था कि प्रतिबिंब का उपयोग किए बिना बाल वर्ग गुणों तक पहुंचने का बेहतर तरीका है या नहीं। –

+0

मुझे इसका उद्देश्य समझ में नहीं आता है। आपके उदाहरण में आप 'कंसोल। राइटलाइन (hsObj.rooms) के साथ बाल संपत्ति का नाम हार्ड-कोडिंग कर रहे हैं; '। आप भी 'hsObj = (हाउस) hsObj.getPropertyVal (hsObj) से छुटकारा पा सकते हैं; 'पूरी तरह से लाइन। प्रतिबिंब पूरी तरह बर्बाद हो गया है। क्या आप जो हासिल करने की कोशिश कर रहे हैं उसके बेहतर उदाहरण के साथ आ सकते हैं? – Dan

उत्तर

5

सबसे पहले, आपका प्रोग्राम.c वास्तव में जो भी आप चाहते हैं वह "करते" नहीं करता है। ऐसा लगता है कि आप एक प्रोग्राम चाहते हैं ताकि आप यह कर सकें:

Asset myAsset = new House(); 
myAsset.Rooms = 5; 

लेकिन, आप वैसे भी ऐसा क्यों करना चाहते हैं? आपकी संपत्ति एक घर नहीं है, तो यह तो आप है कि पहले की जाँच करने की आवश्यकता होगी, एक अपवाद फेंक देगा:

if (myAsset is House) 
    myAsset.Rooms = 5; 

उस बिंदु पर, आप के रूप में अच्छी बस इसे एक सभा में हालांकि डाली हो सकता है। ऐसा लगता है कि आप विरासत के बजाय एक संपत्तिबैग या शब्दकोश का उपयोग करना चाह सकते हैं।

मुझे लगता है कि आप जो वर्णन कर रहे हैं वह यह है। ध्यान दें कि विकल्प 1 वास्तव में प्रतिबंधित नहीं करता है कि कौन से गुणों का उपयोग कक्षाओं पर किया जा सकता है, इसलिए मुझे लगता है कि यह वास्तव में आपके विशिष्ट मामले के लिए काम नहीं करेगा।

// Option 1 
Asset asset = new House(); 
asset.SetProperty("Rooms", 5); 
var rooms = asset.GetProperty<int>("Rooms"); 

// Option 2 
Asset asset = new House(); 
asset.SetProperty("Rooms", 5); 
asset.SetProperty("SomePropertyOnAsset", 10); 
asset.SetProperty("SomethingElse", 15); // Throws ArgumentException 

एक 3 विकल्प एसेट एक DynamicObject बनाना है:

// Option 1, a Property Bag (Note: this replaces the properties on the classes) 
class Asset 
{ 
    Dictionary<string, object> myPropertyBag = new Dictionary<string, object>(); 

    public T GetProperty<T>(string property) 
    { 
     // This throws if the property doesn't exist 
     return (T)myPropertyBag[property]; 
    } 

    public void SetProperty<T>(string property, T value) 
    { 
     // This adds the property if it doesn't exist 
     myPropertyBag[property] = (object)value; 
    } 
} 

// Option 2, use a switch and override this function in derived classes 
class Asset 
{ 
    public int SomePropertyOnAsset { get; set; } 

    public virtual T GetProperty<T>(string property) 
    { 
     switch (property) 
     { 
      case "SomePropertyOnAsset": return this.SomePropertyOnAsset; 

      default: throw new ArgumentException("property"); 
     } 
    } 

    public virtual void SetProperty<T>(string property, T value) 
    { 
     switch (property) 
     { 
      case "SomePropertyOnAsset": this.SomePropertyOnAsset = (int)value; 

      default: throw new ArgumentException("property"); 
     } 
    } 
} 

class House : Asset 
{ 
    public int Rooms { get; set; } 

    public virtual T GetProperty<T>(string property) 
    { 
     switch (property) 
     { 
      case "Rooms": return this.Rooms; 

      default: return base.GetProperty<T>(property); 
     } 
    } 

    public virtual void SetProperty<T>(string property, T value) 
    { 
     switch (property) 
     { 
      case "Rooms": this.Rooms = (int)value; 
       break; 

      default: base.SetProperty<T>(property, value); 
       break; 
     } 
    } 
} 

फिर, इस आप उन्हें कैसे उपयोग करें। http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject.aspx

यदि आप अपने एसेट बेस क्लास में कोई बड़ा बदलाव नहीं करना चाहते हैं या नहीं चाहते हैं, तो प्रत्येक इकाई को स्पर्श करें, आपको शायद प्रतिबिंब का उपयोग करने की आवश्यकता होगी।

+0

मेरे अपडेट की जांच करें। –

+0

धन्यवाद डायनामिक ऑब्जेक्ट क्लास दिलचस्प लगता है। –

1

ल्यूक ग्रेविट शायद सही है। आप बस इसे एक घर में डालना चाहते हैं।

House myHouse = asObj as House; 
if (myHouse != null) 
{ 
    // do some fun house stuff 
} 

Yacht myYacht = asObj as Yacht; 
if (myYacht != null) 
{ 
    // put on monocle 
} 
+0

मेरे लिए काम किया। धन्यवाद! – Willy

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