我有一個C#轉換器方法,它將通用列表與使用反射進行對話。如何在反射中使用索引屬性的SetValue?
的問題,當我嘗試調用該項目的財產SetValue方法時,它拋出以下內部異常(ArgumentOutOfRangeException):
指數超出範圍。必須爲 非負數且小於集合的大小。參數名稱: 索引。
這裏是我的代碼:
internal class Program
{
private static void Main()
{
List<ClassA> classA = new List<ClassA>();
classA.Add(new ClassA { Data = "value1" });
classA.Add(new ClassA { Data = "value2" });
List<ClassB> classB = Converter<List<ClassA>, List<ClassB>>(classA);
}
public static TOut Converter<TIn, TOut>(TIn request)
{
var response = Activator.CreateInstance<TOut>();
PropertyInfo propertyA = typeof(TIn).GetProperty("Item");
PropertyInfo propertyB = typeof(TOut).GetProperty("Item");
int count = (int)typeof(TIn).GetProperty("Count").GetValue(request);
for (int i = 0; i < count; i++)
{
var value = propertyA.GetValue(request, new object[] { i });
var b = CreateBFromA(propertyB, propertyA, value);
propertyB.SetValue(response, b, new object[] { i });
}
return response;
}
private static object CreateBFromA(PropertyInfo propertyB, PropertyInfo propertyA, object value)
{
var b = Activator.CreateInstance(propertyB.PropertyType);
object o = propertyA.PropertyType.GetProperty("Data").GetValue(value);
propertyB.PropertyType.GetProperty("Data").SetValue(b, o);
return b;
}
}
internal class ClassA
{
public string Data { get; set; }
}
internal class ClassB
{
public string Data { get; set; }
public object Other { get; set; }
}
這是一個更大的泛型方法(在這裏我需要使用反射)的一個小例子代碼,所以你可以嘗試並運行它重新生成異常。
如何使用SetValue方法避免此異常?
由於您使用List而不是Array,因此您應該先將對象添加到集合中,然後才能使用索引器。可能執行'typeof(TOut).GetMethod(「Add」)。Invoke(response,new object [] {null});'在'propertyB.SetValue(response,b,new object [] {i})之前''會幫幫我。但我沒有編譯這個,只是猜測。 –
2013-03-04 14:05:36
請原諒我的問題;但是這不會更容易*通過抽象/接口實現? – Richard 2013-03-04 14:20:16
@Marek Kembrowski是的,你是對的。我只能將那些已經添加的元素(在這種情況下)設置爲集合。 – ZYD 2013-03-04 15:26:42