2008-11-14 14 views
22

मैं प्रतिबिंब का उपयोग कर क्लोन विधि लिख रहा हूं। मैं कैसे पता लगा सकता हूं कि संपत्ति प्रतिबिंब का उपयोग कर एक अनुक्रमित संपत्ति है?सी # प्रतिबिंब अनुक्रमित गुण

public string[] Items 
{ 
    get; 
    set; 
} 

मेरे विधि अब तक: उदाहरण के लिए:

public static T Clone<T>(T from, List<string> propertiesToIgnore) where T : new() 
{ 
    T to = new T(); 

    Type myType = from.GetType(); 

    PropertyInfo[] myProperties = myType.GetProperties(); 

    for (int i = 0; i < myProperties.Length; i++) 
    { 
     if (myProperties[i].CanWrite && !propertiesToIgnore.Contains(myProperties[i].Name)) 
     { 
      myProperties[i].SetValue(to,myProperties[i].GetValue(from,null),null); 
     } 
    } 

    return to; 
} 
+13

एक अनुक्रमित संपत्ति नहीं है यही कारण है कि करने के लिए इंडेक्सर परिवर्तित कर सकते हैं, कि एक संपत्ति है कि एक सरणी देता है। –

+3

इस प्रश्न को मॉडरेटर द्वारा बदला जाना आवश्यक है। इंडेक्सर प्रॉपर्टी खोजने के लिए यह शीर्ष Google परिणाम है, लेकिन कोड उदाहरण उदाहरण के लिए यह नहीं है। नीचे दिए गए आधे उत्तर प्रश्न और आधा कोड उदाहरण का जवाब देते हैं। –

उत्तर

40
if (propertyInfo.GetIndexParameters().Length > 0) 
{ 
    // Property is an indexer 
} 
8

क्या आप चाहते हैं GetIndexParameters() तरीका है। यदि वह सरणी जो लौटाती है तो 0 से अधिक आइटम हैं, इसका मतलब है कि यह एक अनुक्रमित संपत्ति है। अधिक जानकारी के लिए

the MSDN documentation देखें।

20

क्षमा करें, लेकिन

public string[] Items { get; set; } 

नहीं एक अनुक्रमित संपत्ति है, यह एक सरणी प्रकार के केवल है! निम्नलिखित हालांकि है:

 
foreach (PropertyInfo property in obj.GetType().GetProperties()) 
{ 
    object value = property.GetValue(obj, null); 
    if (value is object[]) 
    { 
    .... 
    } 
} 

पी.एस.:

public string this[int index] 
{ 
    get { ... } 
    set { ... } 
} 
+1

ठीक है, लेकिन आप इसे प्रतिबिंब के माध्यम से कैसे ढूंढते हैं? – BrainSlugs83

1

यहाँ कुछ कोड है कि मेरे लिए काम किया है .GetIndexParameters().Length > 0) इस आलेख में वर्णित मामले के लिए काम करता है: http://msdn.microsoft.com/en-us/library/b05d59ty.aspx तो यदि आप टाइप स्ट्रिंग के मान के लिए चार्स नाम की संपत्ति की परवाह करते हैं, तो इसका उपयोग करें, लेकिन यह उन अधिकांश सरणीओं के लिए काम नहीं करता है जिनमें मुझे रूचि है, सहित, मैं भी हूं बहुत यकीन है, मूल प्रश्न से एक स्ट्रिंग सरणी।

2

यदि आप property.GetValue(obj,null) पर कॉल करते हैं, और संपत्ति अनुक्रमित है, तो आपको पैरामीटर गिनती मिस्चैच अपवाद मिलेगा। यह जांचने के लिए बेहतर है कि संपत्ति GetIndexParameters() का उपयोग करके अनुक्रमित है या नहीं और फिर तय करें कि क्या करना है।

0

आप IEnumerable

public static IEnumerable<T> AsEnumerable<T>(this object o) where T : class { 
     var list = new List<T>(); 
     System.Reflection.PropertyInfo indexerProperty = null; 
     foreach (System.Reflection.PropertyInfo pi in o.GetType().GetProperties()) { 
      if (pi.GetIndexParameters().Length > 0) { 
       indexerProperty = pi; 
       break; 
      } 
     } 

     if (indexerProperty.IsNotNull()) { 
      var len = o.GetPropertyValue<int>("Length"); 
      for (int i = 0; i < len; i++) { 
       var item = indexerProperty.GetValue(o, new object[]{i}); 
       if (item.IsNotNull()) { 
        var itemObject = item as T; 
        if (itemObject.IsNotNull()) { 
         list.Add(itemObject); 
        } 
       } 
      } 
     } 

     return list; 
    } 


    public static bool IsNotNull(this object o) { 
     return o != null; 
    } 

    public static T GetPropertyValue<T>(this object source, string property) { 
     if (source == null) 
      throw new ArgumentNullException("source"); 

     var sourceType = source.GetType(); 
     var sourceProperties = sourceType.GetProperties(); 
     var properties = sourceProperties 
      .Where(s => s.Name.Equals(property)); 
     if (properties.Count() == 0) { 
      sourceProperties = sourceType.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic); 
      properties = sourceProperties.Where(s => s.Name.Equals(property)); 
     } 

     if (properties.Count() > 0) { 
      var propertyValue = properties 
       .Select(s => s.GetValue(source, null)) 
       .FirstOrDefault(); 

      return propertyValue != null ? (T)propertyValue : default(T); 
     } 

     return default(T); 
    } 
+0

मुझे लगता है कि यह केवल एकल-पूर्णांक-सूचकांक गुणों को संभालता है, है ना? कोई स्ट्रिंग-आधारित इंडेक्सर्स नहीं, कोई एकाधिक इंडेक्स पैरामीटर नहीं ... या क्या मुझे कुछ याद आ रही है? –

+0

@ कोड जॉकी - आप सही हो सकते हैं; मुझे इसे 'स्ट्रिंग' इनपुट प्रकार के साथ काम करने में परेशानी हो रही है। यह 'चार्स' अनुक्रमित संपत्ति पर लटक रहा है। जब तक मैं खुद कुछ याद नहीं कर रहा हूँ ... – InteXX

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