【问题标题】:PropertyInfo.GetValue() - how do you index into a generic parameter using reflection in C#?PropertyInfo.GetValue() - 如何在 C# 中使用反射索引泛型参数?
【发布时间】:2009-06-01 22:59:34
【问题描述】:

这个(缩短的)代码..

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

.. 正在引发“TargetParameterCountException:参数计数不匹配”异常。

'propertyInfo' 的基础类型是一些 T 的集合。'count' 是集合中的项目数。我需要遍历集合并对 obj 执行操作。

建议。

【问题讨论】:

    标签: c# generics reflection


    【解决方案1】:

    反射一次只能在一个级别上起作用。

    你试图索引属性,这是错误的。

    相反,读取属性的值,以及您返回的对象,这就是您需要索引的对象。

    这是一个例子:

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

    【讨论】:

    • 好的,我明白了,感谢您的回复。它现在正在工作,但如果有人知道的话,有兴趣了解“Item”属性...
    • 找到了,改了答案。属性在类上,而不是在属性上。请注意,没有索引器的类也没有该属性。
    • 注意 - 我在我的代码中进一步进行收集检查。感谢您的更新:)
    【解决方案2】:

    在我看到这个之前,我大部分时间都在那里,我发布这个是因为我在其他任何地方都没有看到它;关键是使用 GetValue(collection, new Object[] { i });在循环中而不是尝试使用 GetValue(collection, new Object[i]);在循环之外。 (在我的示例中,您可能可以忽略“输出”);

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

    【讨论】:

      【解决方案3】:
      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);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-14
        相关资源
        最近更新 更多