Создание объекта с помощью отражения с анонимным типом

1

Я использую следующий метод для создания объекта посредством отражения

 Activator.CreateInstance(Type type, params object[] parameters)

Где "параметры" - это список параметров, переданных конструктору во время выполнения.

Тем не менее, я хотел бы, чтобы этот процесс был более интуитивным для других разработчиков в команде и вместо того, чтобы передавать массив объектов [], я хотел бы, чтобы они передавали анонимный объект, например

 // note, invalid code
 Activator.CreateInstance(typeof(MyType), new { paramName1 = "abc", paramName2 = "xyz})

Поскольку метод framework не поддерживает его, имеет ли кто-нибудь пример кода, который переводит анонимный объект в массив? Обратите внимание, что порядок параметров важен для метода Activator.CreateInstance(), так как он выполняет сопоставление параметров. Очевидно, что это склонность к ошибкам, поэтому я предпочел бы использовать анонимный тип.

Любые предложения с удовольствием оценены.

Алек.

Теги:
reflection

1 ответ

4
Лучший ответ

Для этого я бы не использовал Activator.CreateInstance. Я бы использовал Type.GetConstructors() чтобы получить все конструкторы, а затем найти тот, который имеет такое же количество параметров, что и у анонимного типа, и с теми же именами. Если может быть несколько таких конструкторов с разными типами, вам нужно добавить дополнительную логику, чтобы проверить, что каждый тип параметра совместим с соответствующим типом свойства.

Что-то вроде:

public object CreateInstance(Type type, Object parameterMapping)
{
    var ctors = type.GetConstructors();
    var properties = parameterMapping.GetType().GetProperties();
    foreach (var ctor in ctors)
    {
        var parameters = ctor.GetParameters();
        if (parameters.Length != properties.Length)
        {
            continue;
        }
        object[] args = new object[parameters.Length];
        bool success = true;
        for (int i = 0; i < parameters.Length; 
        {
            var property = parameterMapping.GetType().GetProperty(parameter.Name);
            if (property == null)
            {
                success = false;
                break;
            }
            // TODO: Check property type is appropriate too
            args[i] = property.GetValue(parameterMapping, null);
        }
        if (!success)
        {
            continue;
        }
        return ctor.Invoke(args);
    }
    throw new ArgumentException("No suitable constructor found");
}
  • 0
    Замечательно, спасибо большое. Не знал, что вы могли бы сделать ctor.Invoke ()

Ещё вопросы

Сообщество Overcoder
Наверх
Меню