C# 反射:从程序集创建对象而不调用构造函数信息
C# Reflection: Create object from assembly without invoking constructorinfo
我在使用反射调用构造函数时遇到问题。
无参数构造函数没有问题,但是当我尝试调用具有参数的 once 时,我得到 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 并放入 new Guid() 它会起作用:
return Activator.CreateInstance(type, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, new Guid(), null);
问题:如何调用构造函数?
从中找到了一些线索:
How to identify each parameter type in a C# method?
@JaredPar 说了以下内容:
要获取参数的实际类型,请使用 ParameterInfo 值上的 ParameterType。使用该值,您可以通过多种方式使用它来识别类型。最简单的方法是直接与已知类型进行比较。
所以在我的例子中,我需要识别 parameterType 的类型并创建该类型的新实例,然后再将其发送给构造函数。
因为我只关心对象的类型,所以可以通过
来解析
var fixture = new Fixture(); //Ploeh.AutoFixture
var obj = new SpecimenContext(fixture).Resolve(asmtype); //Ploeh.AutoFixture.Kernel.SpecimenContext
所以在获得 assemblytype 之后,我只创建了一个 fixture 和一个带有 fixture 的 specimumtContext,然后解析 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);
}
我在使用反射调用构造函数时遇到问题。 无参数构造函数没有问题,但是当我尝试调用具有参数的 once 时,我得到 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 并放入 new Guid() 它会起作用:
return Activator.CreateInstance(type, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, new Guid(), null);
问题:如何调用构造函数?
从中找到了一些线索:
How to identify each parameter type in a C# method?
@JaredPar 说了以下内容: 要获取参数的实际类型,请使用 ParameterInfo 值上的 ParameterType。使用该值,您可以通过多种方式使用它来识别类型。最简单的方法是直接与已知类型进行比较。
所以在我的例子中,我需要识别 parameterType 的类型并创建该类型的新实例,然后再将其发送给构造函数。
因为我只关心对象的类型,所以可以通过
来解析var fixture = new Fixture(); //Ploeh.AutoFixture
var obj = new SpecimenContext(fixture).Resolve(asmtype); //Ploeh.AutoFixture.Kernel.SpecimenContext
所以在获得 assemblytype 之后,我只创建了一个 fixture 和一个带有 fixture 的 specimumtContext,然后解析 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);
}