PropertyInfo.GetValue() - как вы индексируете в общий параметр, используя отражение в С#?
Этот (сокращенный) код..
for (int i = 0; i < count; i++)
{
object obj = propertyInfo.GetValue(Tcurrent, new object[] { i });
}
.. бросает исключение "TargetParameterCountException: несоответствие счетчика параметров".
Подходящим типом 'propertyInfo' является коллекция некоторого T. 'count' - количество элементов в коллекции. Мне нужно выполнить итерацию по коллекции и выполнить операцию на obj.
Рекомендации оценены.
Ответы
Ответ 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 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
Я был в основном там, пока не увидел это, и я публикую это, потому что я не видел его нигде; ключ использовал GetValue (коллекция, новый Object [] {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;
}
Ответ 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);
}