如何从可能实现 IEnumerable<T> 的对象中提取 MethodInfo.Invoke 参数
How to extract MethodInfo.Invoke parameters from an object maybe implementing IEnumerable<T>
使用反射,我试图在预期为某种类型的 IEnumerable 的对象上调用 Linq 方法 IEnumerable.FirstOrDefault(),并 return 结果对象。
我有以下 类:
class MyClass : IEnumerable<MyOtherClass>
{
public IEnumerator<MyOtherClass> GetEnumerator() { yield return new MyOtherClass(); }
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
class MyOtherClass { }
这就是我尝试调用该方法和 return 结果的方式:
object GetFirstItemFromObject(object objectThatIsExpectedToImplementIEnumerableT)
{
Type genericType =
objectThatIsExpectedToImplementIEnumerableT
.GetType()
.GetInterfaces()
.Where(@interface => @interface.Name == "IEnumerable`1")
.FirstOrDefault()
?.GenericTypeArguments
?.First()
?? throw new ArgumentException("Object does not implement IEnumerable<T>.");
var methodInfo =
typeof(Enumerable)
.GetMethods(BindingFlags.Public | BindingFlags.Static)
.Where(methodInfo1 => methodInfo1.Name == "FirstOrDefault")
.Select(method => method.MakeGenericMethod(new[] { genericType }))
.FirstOrDefault()
?? throw new ArgumentException("Object does not have method member FirstOrDefault.");
return methodInfo.Invoke(objectThatIsExpectedToImplementIEnumerableT, new object[] { });
}
我预计向该方法提供一个新的 MyClass
会 return 一个新的 MyOtherClass
,但它失败了,因为 methodInfo.Invoke
需要参数数组中的单个对象.
System.Reflection.TargetParameterCountException: 'Parameter count mismatch.'
我不知道要为这个方法提供什么,或者不明白我要提供什么,或者我为什么要提供它。
如果我提供 some 类型,我会得到以下异常:
System.ArgumentException: 'Object of type 'System.RuntimeType' cannot be converted to type 'System.Collections.Generic.IEnumerable`1[MyNamespace.MyOtherClass]'.'
其他线程似乎没有解决 MethodInfo
的调用问题,或者假定提供给 MakeGenericMethod
的类型在设计时可用,或者给 MethodInfo.Invoke
的参数数组为 null 或空。
我欢迎任何有助于理解这个问题的帮助,并且假设我找到泛型类型以作为类型参数提供给 MakeGenericMethod
的代码至少在功能上是正确的,我应该提供给 methodInfo.Invoke
,为什么?
return methodInfo.Invoke(objectThatIsExpectedToImplementIEnumerableT, new object[] { ??? });
你根本不需要反思。 IEnumerable<T>
继承自 IEnumerable
,您可以使用 Cast<T>()
:
从 IEnumerable
获取 IEnumerable<object>
object GetFirstItemFromObject(object objectThatIsExpectedToImplementIEnumerableT)
{
var enumerableObject = (IEnumerable)objectThatIsExpectedToImplementIEnumerableT;
return enumerableObject.Cast<object>().FirstOrDefault();
}
FirstOrDefault 是一个扩展方法,您需要将 this
作为参数传递
return methodInfo.Invoke(null, new object[] {objectThatIsExpectedToImplementIEnumerableT });
使用反射,我试图在预期为某种类型的 IEnumerable 的对象上调用 Linq 方法 IEnumerable.FirstOrDefault(),并 return 结果对象。
我有以下 类:
class MyClass : IEnumerable<MyOtherClass>
{
public IEnumerator<MyOtherClass> GetEnumerator() { yield return new MyOtherClass(); }
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
class MyOtherClass { }
这就是我尝试调用该方法和 return 结果的方式:
object GetFirstItemFromObject(object objectThatIsExpectedToImplementIEnumerableT)
{
Type genericType =
objectThatIsExpectedToImplementIEnumerableT
.GetType()
.GetInterfaces()
.Where(@interface => @interface.Name == "IEnumerable`1")
.FirstOrDefault()
?.GenericTypeArguments
?.First()
?? throw new ArgumentException("Object does not implement IEnumerable<T>.");
var methodInfo =
typeof(Enumerable)
.GetMethods(BindingFlags.Public | BindingFlags.Static)
.Where(methodInfo1 => methodInfo1.Name == "FirstOrDefault")
.Select(method => method.MakeGenericMethod(new[] { genericType }))
.FirstOrDefault()
?? throw new ArgumentException("Object does not have method member FirstOrDefault.");
return methodInfo.Invoke(objectThatIsExpectedToImplementIEnumerableT, new object[] { });
}
我预计向该方法提供一个新的 MyClass
会 return 一个新的 MyOtherClass
,但它失败了,因为 methodInfo.Invoke
需要参数数组中的单个对象.
System.Reflection.TargetParameterCountException: 'Parameter count mismatch.'
我不知道要为这个方法提供什么,或者不明白我要提供什么,或者我为什么要提供它。
如果我提供 some 类型,我会得到以下异常:
System.ArgumentException: 'Object of type 'System.RuntimeType' cannot be converted to type 'System.Collections.Generic.IEnumerable`1[MyNamespace.MyOtherClass]'.'
其他线程似乎没有解决 MethodInfo
的调用问题,或者假定提供给 MakeGenericMethod
的类型在设计时可用,或者给 MethodInfo.Invoke
的参数数组为 null 或空。
我欢迎任何有助于理解这个问题的帮助,并且假设我找到泛型类型以作为类型参数提供给 MakeGenericMethod
的代码至少在功能上是正确的,我应该提供给 methodInfo.Invoke
,为什么?
return methodInfo.Invoke(objectThatIsExpectedToImplementIEnumerableT, new object[] { ??? });
你根本不需要反思。 IEnumerable<T>
继承自 IEnumerable
,您可以使用 Cast<T>()
:
IEnumerable
获取 IEnumerable<object>
object GetFirstItemFromObject(object objectThatIsExpectedToImplementIEnumerableT)
{
var enumerableObject = (IEnumerable)objectThatIsExpectedToImplementIEnumerableT;
return enumerableObject.Cast<object>().FirstOrDefault();
}
FirstOrDefault 是一个扩展方法,您需要将 this
作为参数传递
return methodInfo.Invoke(null, new object[] {objectThatIsExpectedToImplementIEnumerableT });