PropertyInfo.GetValue() - how do you index into a generic parameter using reflection in C#?

后端 未结 3 1698
渐次进展
渐次进展 2021-01-02 01:52

This (shortened) code..

for (int i = 0; i < count; i++)
{
    object obj = propertyInfo.GetValue(Tcurrent, new object[] { i });
}

.. is

相关标签:
3条回答
  • 2021-01-02 02:12
    Assembly zip_assembly = Assembly.LoadFrom(@"C:\Ionic.Zip.Reduced.dll");
    Type ZipFileType = zip_assembly.GetType("Ionic.Zip.ZipFile");
    Type ZipEntryType = zip_assembly.GetType("Ionic.Zip.ZipEntry");
    string local_zip_file = @"C:\zipfile.zip";
    object zip_file = ZipFileType.GetMethod("Read", new Type[] { typeof(string) }).Invoke(null, new object[] { local_zip_file });
    
    // Entries is ICollection<ZipEntry>
    IEnumerable entries = (IEnumerable)ZipFileType.GetProperty("Entries").GetValue(zip_file, null);
    foreach (object entry in entries)
    {
        string file_name = (string)ZipEntryType.GetProperty("FileName").GetValue(entry, null);
        Console.WriteLine(file_name);
    }
    
    0 讨论(0)
  • 2021-01-02 02:29

    Reflection only works on one level at a time.

    You're trying to index into the property, that's wrong.

    Instead, read the value of the property, and the object you get back, that's the object you need to index into.

    Here's an example:

    using System;
    using System.Collections.Generic;
    using System.Reflection;
    
    namespace DemoApp
    {
        public class TestClass
        {
            public List<Int32> Values { get; private set; }
    
            public TestClass()
            {
                Values = new List<Int32>();
                Values.Add(10);
            }
        }
    
        class Program
        {
            static void Main()
            {
                TestClass tc = new TestClass();
    
                PropertyInfo pi1 = tc.GetType().GetProperty("Values");
                Object collection = pi1.GetValue(tc, null);
    
                // note that there's no checking here that the object really
                // is a collection and thus really has the attribute
                String indexerName = ((DefaultMemberAttribute)collection.GetType()
                    .GetCustomAttributes(typeof(DefaultMemberAttribute),
                     true)[0]).MemberName;
                PropertyInfo pi2 = collection.GetType().GetProperty(indexerName);
                Object value = pi2.GetValue(collection, new Object[] { 0 });
    
                Console.Out.WriteLine("tc.Values[0]: " + value);
                Console.In.ReadLine();
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-02 02:31

    I was most of the way there until I saw this, and I am posting this because I didn't see it anywhere else; the key was using GetValue(collection, new Object[] { i }); in the loop rather than trying to use GetValue(collection, new Object[i]); outside the loop. (You can probably ignore the "output" in my example);

    private static string Recursive(object o)
    { 
            string output="";
            Type t = o.GetType();
            if (t.GetProperty("Item") != null)
            {
                System.Reflection.PropertyInfo p = t.GetProperty("Item");
                int count = -1;
                if (t.GetProperty("Count") != null && 
                    t.GetProperty("Count").PropertyType == typeof(System.Int32))
                {
                    count = (int)t.GetProperty("Count").GetValue(o, null);
                }
                if (count > 0)
                {
                    object[] index = new object[count];
                    for (int i = 0; i < count; i++)
                    {
                        object val = p.GetValue(o, new object[] { i });
                        output += RecursiveWorker(val, p, t);
                    }
                }
           }
           return output;        
    }
    
    0 讨论(0)
提交回复
热议问题