PropertyInfo.GetValue () - как вы индексируете в универсальный параметр, используя отражение в C #? - PullRequest
13 голосов
/ 02 июня 2009

Этот (сокращенный) код ..

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

.. генерирует исключение 'TargetParameterCountException: Несоответствие количества параметров'.

Базовый тип 'propertyInfo' - это Коллекция некоторого T. 'count' - это количество элементов в коллекции. Мне нужно перебрать коллекцию и выполнить операцию над объектом.

Советы приветствуются.

Ответы [ 3 ]

19 голосов
/ 02 июня 2009

Отражение работает только на одном уровне одновременно.

Вы пытаетесь проиндексировать свойство, это неправильно.

Вместо этого прочитайте значение свойства, и объект, который вы возвращаете, - это тот объект, в который нужно индексировать.

Вот пример:

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();
        }
    }
}
2 голосов
/ 19 июня 2009

Я был там большую часть пути, пока не увидел это, и я публикую это, потому что больше нигде не видел; ключ использовал GetValue (коллекция, новый объект [] {i}); в цикле, а не пытаться использовать GetValue (коллекция, новый 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;        
}
0 голосов
/ 11 июля 2012
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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...