C#反射-如何获取要传递给泛型方法的接口

本文关键字:泛型方法 接口 获取 反射 何获取 | 更新日期: 2024-09-20 19:24:10

对于单元测试,我使用RhinoMock,在下面的示例中,您可以看到我成功地创建了一个基于接口ISomething:的Stub

var stub = MockRepository.GenerateStub<ISomething>();

一切都很好。

然而,我正在编写一个测试,该测试使用反射在对象的属性中循环,然后我想基于当前属性动态创建一个存根。

所以,想象一下,我测试的班级是Parent:

public class Parent
{
    public ISomething Prop1 {get;set;}
    public ISomethingElse Prop2 {get;set;}
    public ISomethingEntirelyDifferent Prop3 {get;set;}
}

使用反射,我可以使用获得单独的属性

typeof(parent).GetProperties(BindingFlags.Public | BindingFlags.Instance)

当我遍历每个属性时,我会使用在当前属性上看到接口的名称(ISomething、ISomethingElse、ISomechingEntiirelyDifferent)

p.PropertyType.Name

但我不知道如何将其插入:

var stub = MockRepository.GenerateStub<????>();

C#反射-如何获取要传递给泛型方法的接口

您必须使用MethodInfo.MakeGenericMethod方法。

var propertyType = propertyInfo.PropertyType;
var openGenericMethod = typeof(MockRepository).GetMethod("GenerateStub");
var closedGenericMethod = openGenericMethod.MakeGenericMethod(propertyType);
var stub = closedGenericMethod.Invoke(null, null);

当有多个GenerateStub方法(泛型、非泛型…)时,可以使用GetMethods(),然后使用Linqs Single方法来找到正确的方法。

更新:在检查了所需的方法后,发现该方法具有params object[] objects参数。这就是为什么使用null值调用时会得到TargetParameterCountException的原因。要解决这个问题,您必须传递一个换行的空对象数组。这对我有效:

var propertyType = propertyInfo.PropertyType;
var openGenericMethod = typeof (MockRepository).GetMethods()
        .Single(x => x.Name == "GenerateStub" && x.IsGenericMethod);
var closedGenericMethod = openGenericMethod.MakeGenericMethod(propertyType);
var stub = closedGenericMethod.Invoke(null,  new object[] { new object[0] });