c#反射:从程序集创建对象而不调用constructorinfo

本文关键字:调用 constructorinfo 创建对象 程序集 反射 | 更新日期: 2023-09-27 18:04:00

我用反射调用构造函数有问题。无参数构造函数是没有问题的,但当我试图调用一次有参数我得到missingMethodException

代码:

 if (type != null)
        {
            var constructor = type.GetConstructor(Type.EmptyTypes);
            if (constructor != null)
               return Activator.CreateInstance(type);
            constructor = type.GetConstructors()[0];
            var parameters = constructor.GetParameters();
            var obj = new object[parameters.Length];
            for (var i = 0; i < parameters.Length; i++)
            {
                obj[i] = (object) parameters[i].ParameterType;
            }
            return Activator.CreateInstance(type, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, obj, null);
        }

无参数构造函数工作得很好。

 var constructor = type.GetConstructor(Type.EmptyTypes);
            if (constructor != null)
            {
                return Activator.CreateInstance(type);
            }

这部分没有:

   constructor = type.GetConstructors()[0];
            var parameters = constructor.GetParameters();
            var obj = new object[parameters.Length];
            for (var i = 0; i < parameters.Length; i++)
            {
                obj[i] = (object) parameters[i].ParameterType;
            }
            return Activator.CreateInstance(type, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, obj, null);
        }

我知道其中一个构造函数是这样的:

 public class YYY: XXX
{
    public YYY(Guid customerId)
        : base(404, Level.Warn, null, string.Format("{0}",customerId))
    {
    }
}

我也知道parameterType不是构造函数想要的数据类型:

parameters[i].ParameterType is Guid
false

和. .我知道,如果我删除obj并添加新的Guid(),它将工作:

return Activator.CreateInstance(type, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, new Guid(), null);

问题:如何调用构造函数?

c#反射:从程序集创建对象而不调用constructorinfo

找到了一些线索

如何识别c#方法中的每个参数类型?

其中@JaredPar表示:要获取参数的实际类型,请使用ParameterInfo值上的ParameterType。有了这个值,有几种方法可以使用它来识别类型。最简单的方法是与已知类型直接比较。

所以在我的例子中,我需要识别parameterType的类型,并在将其发送给构造函数之前创建该类型的新实例。

因为我只关心对象的类型,所以我可以通过

来解析它
var fixture = new Fixture(); //Ploeh.AutoFixture
var obj = new SpecimenContext(fixture).Resolve(asmtype); //Ploeh.AutoFixture.Kernel.SpecimenContext 

所以在得到装配类型之后,我只是创建一个夹具和一个带有夹具的标本上下文,然后解析asmType。

该对象将是对应的类型。

所以最终结果:

   foreach (var asmtype in assemblyTypes)
        {
            var fixture = new Fixture();
            var obj = new SpecimenContext(fixture).Resolve(asmtype);
            _handler.Error(new Login { BrandId = _brandId }, new Domain.Entities.Customer { CustomerId = It.IsAny<Guid>() }, (Exception) obj);
            if (obj is InvalidCredentialsException)
                _loginRepository.Verify(v => v.ZZZ(It.IsAny<Guid>(), It.IsAny<int>()), Times.Once);
            else
                _loginRepository.Verify(v => v.ZZZ(It.IsAny<Guid>(), It.IsAny<int>()), Times.Never);
        }