C#Reflection - 如何让接口传递给泛型方法?

时间:2016-04-15 11:24:19

标签: c# reflection

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

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

一切都很好。

但是,我正在编写一个使用Reflection循环遍历对象属性的测试,然后我想根据当前属性动态创建一个存根。

所以,想象一下我受测试的课程是父母:

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

使用Reflection我可以使用以下方法获取各个属性:

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

当我遍历每个属性时,我使用以下命令在当前属性上看到接口的名称(ISomething,ISomethingElse,ISomethingEntirelyDifferent):

p.PropertyType.Name

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

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

1 个答案:

答案 0 :(得分:1)

您必须使用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] });