补充一下 - 对于不可变结构体,你可能需要对构造函数进行参数匹配。不幸的是,当存在多个构造函数时,这很棘手,特别是某些类型具有单独的静态“Create”方法而不是公共构造函数。但是假设你已经完成了匹配,仍然可以使用Activator.CreateInstance
:
Type type = typeof(Padding); // just an example
object[] args = new object[] {1,2,3,4};
object obj = Activator.CreateInstance(type, args);
然而,选择构造函数的代码(上面有3个...)并不容易。你可以说“选择最复杂的”,然后尝试将参数名称与属性名称(不区分大小写)进行匹配...
一个天真的例子:
static void Main() {
Dictionary<string, object> propertyBag =
new Dictionary<string, object>();
propertyBag["Left"] = 1;
propertyBag["Top"] = 2;
propertyBag["Right"] = 3;
propertyBag["Bottom"] = 4;
Type type = typeof(Padding);
object obj = CreateObject(type, propertyBag);
}
static object CreateObject(Type type, IDictionary<string,object> propertyBag)
{
ConstructorInfo[] ctors = type.GetConstructors();
propertyBag = new Dictionary<string, object>(
propertyBag, StringComparer.OrdinalIgnoreCase);
ConstructorInfo bestCtor = null;
ParameterInfo[] bestParams = null;
for (int i = 0; i < ctors.Length; i++)
{
ParameterInfo[] ctorParams = ctors[i].GetParameters();
if (bestCtor == null || ctorParams.Length > bestParams.Length)
{
bestCtor = ctors[i];
bestParams = ctorParams;
}
}
if (bestCtor == null) throw new InvalidOperationException(
"Cannot create - no constructor");
object[] args = new object[bestParams.Length];
for (int i = 0; i < bestParams.Length; i++)
{
args[i] = propertyBag[bestParams[i].Name];
propertyBag.Remove(bestParams[i].Name);
}
object obj = bestCtor.Invoke(args);
return obj;
}
byte
类型怎么办?由于它是不可变的,我不能在创建实例后直接设置其值。如何使用Activator
设置其值? - Michael Haddad