2010-04-26 17 views
18

बेस क्लास में किसी संपत्ति के नाम से मेल खाने वाली व्युत्पन्न कक्षा में एक संपत्ति घोषित करना (जब तक यह override कीवर्ड के साथ ओवरराइड नहीं करता)। आधार और व्युत्पन्न वर्ग गुण दोनों Type.GetProperties() द्वारा वापस लौटाए जाएंगे यदि उनके प्रकार मेल नहीं खाते हैं। हालांकि, अगर उनके प्रकार मैच करते हैं, तो सदमे से केवल व्युत्पन्न वर्ग की संपत्ति वापस आती है। उदाहरण के लिए:संपत्ति छिपाने और प्रतिबिंब (सी #)

class A 
{ 
    protected double p; 
    public int P { get { return (int)p; } set { p = value; } } 
} 
class B : A 
{ 
    public new int P { get { return (int)p; } set { p = value; } } 
} 
class C : B 
{ 
    public new float P { get { return (float)p; } set { p = value; } } 
} 

typeof(C).GetProperties() कॉलिंग केवल रक्तचाप और सी.पी. वापस आ जाएगी क्या GetProperties() को इस तरह से कॉल करना संभव है कि तीनों को वापस कर दें? विरासत पदानुक्रम को पार करके लगभग निश्चित रूप से ऐसा करने का एक तरीका है, लेकिन क्या एक क्लीनर समाधान है?

+0

तुम क्यों इस तरह के एक वर्ग पदानुक्रम करना चाहते हैं? – driis

+1

@ ड्रिइस: यह चित्रण करने के लिए सिर्फ एक मामूली उदाहरण है। लेकिन, तर्क के लिए, मान लीजिए कि इस वर्ग पदानुक्रम मेरे अलावा किसी अन्य व्यक्ति द्वारा लिखा गया है, लेकिन मुझे अभी भी अपने सभी सार्वजनिक गुणों, यहां तक ​​कि छिपे हुए लोगों को भी ढूंढना होगा। –

+0

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

उत्तर

5

GetProperties को प्रकार के सभी सार्वजनिक गुणों के रूप में परिभाषित किया गया है।

आप का उपयोग कर अपने प्राप्त और सेट तरीकों मिल सकता है:

typeof(C).GetMethods() 
     .Where(m => m.Name.StartsWith("set_") || m.Name.StartsWith("get_")) 

इस वंशानुगत पदानुक्रम नीचे जा रहा गुण प्राप्त करने की तुलना में एक बुरा विचार की तरह लगता है हालांकि,।

+1

तब आपको लगता है कि माता-पिता में से एक को छिपाने वाली get_P विधि के साथ आपको एक ही समस्या होगी, मुझे लगता है। – driis

+1

@Yuriy: typeof (सी) .GetMethods()। @driis: नहीं, ऐसा लगता है कि यह ठीक से काम करता है। –

+0

मैंने अभी कोशिश की। मुझे सभी मिलते हैं 6. –

5

मुझे नहीं लगता कि विरासत पदानुक्रम को पार किए बिना यह संभव है। यदि आप एक आम basetype आप कम से रोक सकता है पता है वस्तु के स्थान पर, यह और अधिक कुशल हो जाएगा

public static IEnumerable<PropertyInfo> GetAllProperties(Type t) 
    { 
     while (t != typeof(object)) 
     { 
      foreach (var prop in t.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance)) 
       yield return prop; 
      t = t.BaseType; 
     } 
    } 
बेशक

,,: यह, हालांकि बहुत ज्यादा कोड होने के लिए नहीं है। इसके अलावा, प्रतिबिंब करने में कुछ समय लगेगा, इसलिए परिणाम कैश करें। आखिरकार, निष्पादन के दौरान प्रकार की जानकारी नहीं बदलेगी।

+0

क्या यह उपज कई बार ओवरराइड गुण नहीं करेगा? –

+0

नहीं, क्योंकि उसने बाध्यकारीफ्लैग कहा था। केवल। –

+0

यहां समस्या यह है कि यदि हम अपने वर्ग पदानुक्रम को दोबारा लिखते हैं ताकि बीपी एपी को ओवरराइड कर सके, फिर भी हमें तीन गुण मिलते हैं, भले ही टाइप सी की ऑब्जेक्ट में केवल दो हैं। –

2

प्रतिबिंब के माध्यम से, नया कीवर्ड केवल उत्तराधिकारी संपत्ति को छुपाता है यदि हस्ताक्षर मिलान करता है। मुझे लगता है कि संपत्ति एक्सेसर्स पर प्रतिबिंब मिलान हस्ताक्षर (get_ & set_)। यह कारण है कि GetProperties() रिटर्न प्रकार भिन्न होने पर बीपी और सीपी लौटाता है।

मैंने हाल ही में Fasteflect खोजा जो उन्नत प्रतिबिंब तंत्र प्रदान करता है।

मैंने चेक किया और Fasteflect type.Properties छिपे हुए सदस्यों (पी) के सभी पेड़ लौटाता है। मुझे लगता है कि एपीआई समर्थन के सदस्यों (आभासी/ओवरराइड) और छिपे हुए सदस्यों (नया) अलग ढंग से जो अपने 'समस्या' के लिए एक अच्छी बात है पर विचार करें;)

fasterflect साथ मेरा परीक्षण:

class Class1 
{ 
    public object field1 = null; 

    public virtual object Property1 { get; set; } 

    public object Property2 { get; set; } 

    public string Property3 { get; set; } 
} 

class Class2 : Class1 
{ 
    public new object field1 = null; 

    public override object Property1 { get; set; } 

    public new string Property3 { get; set; } 
} 

class Class3 : Class2 
{ 
    public new string Property3 { get; set; } 
} 

फ़िल्टर समर्थन सदस्यों लेकिन सभी छुपे हुए सदस्यों रिटर्न:

typeof(Class3).Properties(Flags.ExcludeBackingMembers | Flags.Public | Flags.Instance) 
  • typeof (Class3) .properties (Flags.ExcludeBackingMembers | Flags.Public | Flags.Instance) गणना = 5 System.Collections.Generic।IList
    • [0] {System.String Property3} System.Reflection.PropertyInfo
    • [1] {System.Object Property1} System.Reflection.PropertyInfo
    • [2] {System.String Property3} System.Reflection.PropertyInfo
    • [3] {System.Object Property2} System.Reflection.PropertyInfo
    • [4] {System.String Property3} System.Reflection.PropertyInfo
+0

http://msdn.microsoft.com/en-us/library/51y09td4%28VS.71%29.aspx#vclrfnew_newmodifier: कक्षा या संरचना में पेश एक स्थिर, फ़ील्ड, संपत्ति या प्रकार सभी बेस क्लास सदस्यों को छुपाता है वही नाम। –

+0

प्रतिबिंब के माध्यम से नहीं। चूंकि गुण एक्सेसर्स हैं, मुझे लगता है कि प्रतिबिंब मैसेज एक्सेसर विधियों (get_ और set_) पर हस्ताक्षर करता है। – JoeBilly

+0

Fasterflect के कुछ परीक्षण और निरीक्षण के बाद, मैं सुरक्षित रूप से कह सकता हूं कि इस समस्या का उनका जवाब ड्रिस के बराबर है। छिपे हुए सदस्यों को ढूंढने का उनका पुनरावर्ती समाधान उन वर्चुअल गुणों को छोड़ने में असमर्थ है जो ओवरराइड किए गए हैं। (दरअसल, ExcludeBackingMembers ध्वज को किसी भी तरह से सेट करना दोनों मामलों में सभी तीन गुणों को शामिल करता है।) हालांकि, लिंक के लिए धन्यवाद। –

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