Просто добавьте - с неизменными структурами, вам, вероятно, придется выполнить сопоставление параметров с конструктором. К сожалению, это сложно, когда может быть несколько конструкций, особенно потому, что некоторые типы имеют отдельный статический метод «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>();
// these are the values from your xml
propertyBag["Left"] = 1;
propertyBag["Top"] = 2;
propertyBag["Right"] = 3;
propertyBag["Bottom"] = 4;
// the type to create
Type type = typeof(Padding);
object obj = CreateObject(type, propertyBag);
}
static object CreateObject(Type type, IDictionary<string,object> propertyBag)
{
ConstructorInfo[] ctors = type.GetConstructors();
// clone the property bag and make it case insensitive
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);
// TODO: if we wanted, we could apply any unused keys in propertyBag
// at this point via properties
return obj;
}