我从已加载的程序集中读取类型,例如:
var someType = loadedAssemblies
.Where(a => a != null && a.FullName.StartsWith("MY."))
.SelectMany(a => a.GetTypes())
.Distinct()
.ToArray()[0];
如果counstructor有参数,我可以阅读:
ParameterInfo[] parameters = classType.GetConstructors()[0].GetParameters();
我想使用默认参数值调用构造函数,或者如果参数是枚举,则使用第一个枚举值。 如果只有一个参数并且它是枚举,则它的工作方式如下:
object curObject = Activator.CreateInstance(classType, new object[] { parameters[0].ParameterType.GetEnumValues().GetValue(0) });
如果有更多参数,我该怎么做? 我需要创建对象来读取属性:
var propertyInfo = someType.GetProperty("EntityType");
string entityType = propertyInfo.GetValue(curObject, null).ToString();
答案 0 :(得分:6)
好吧,你可以创建自己的Factory和write方法,用它们的默认参数检查类型的构造函数:
public static class MyFactory
{
public static T MyCreateInstance<T>()
where T : class
{
return (T) MyCreateInstance(typeof (T));
}
public static object MyCreateInstance(Type type)
{
var ctor = type
.GetConstructors()
.FirstOrDefault(c => c.GetParameters().Length > 0);
return ctor != null
? ctor.Invoke
(ctor.GetParameters()
.Select(p =>
p.HasDefaultValue? p.DefaultValue :
p.ParameterType.IsValueType && Nullable.GetUnderlyingType(p.ParameterType) == null
? Activator.CreateInstance(p.ParameterType)
: null
).ToArray()
)
: Activator.CreateInstance(type);
}
}
然后你可以使用这个方法:
var classType = loadedAssemblies
.Where(a => a != null && a.FullName.StartsWith("MY."))
.SelectMany(a => a.GetTypes())
.Distinct()
.ToArray()[0];
var curObject = MyFactory.MyCreateInstance(classType);
// This will return an array of values
object[] values = classType
.GetFields()
.Select(f => f.GetValue(curObject))
.ToArray();
P.S。 这是DotNet fiddle example。
更新:
根据您使用的方案更改代码。现在我们有两种方法, 一个返回对象,另一个可以将其转换为类型T.
我还更新了DotnetFiddle,请检查一下。
答案 1 :(得分:2)
您可以创建一个帮助方法来获取类型的默认值:
private static object GetDefaultValue(Type type)
{
if (type.IsEnum) return type.GetEnumValues().GetValue(0);
if (type.IsValueType) return Activator.CreateInstance(type);
return null;
}
然后,您可以获取参数的默认值:
var parameters = constructor.GetParameters()
.Select(p => GetDefaultValue(p.ParameterType))
.ToArray();
并调用ConstructorInfo
来获取实例:
var obj = constructor.Invoke(parameters);
如果构造函数的参数具有默认值并且您想要使用它们,则可以执行以下操作:
var parameters = constructor
.GetParameters()
.Select(p => p.HasDefaultValue ? p.RawDefaultValue : GetDefaultValue(p.ParameterType))
.ToArray();