Как проверить, содержит ли тип конструктор без параметров?

Я хотел бы проверить, не знает ли тип во время выполнения конструктор без параметров. Класс Type не дал ничего перспективного, поэтому я предполагаю, что мне нужно использовать отражение?

Ответ 1

Класс Type является отражением. Вы можете сделать:

Type theType = myobject.GetType(); // if you have an instance
// or
Type theType = typeof(MyObject); // if you know the type

var constructor = theType.GetConstructor(Type.EmptyTypes);

Он вернет значение null, если конструктор без параметров не существует.


Если вы также хотите найти частные конструкторы, используйте немного больше:

var constructor = theType.GetConstructor(
  BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, 
  null, Type.EmptyTypes, null);

Существует предостережение для типов значений, которые не имеют конструктора по умолчанию. Вы можете проверить, есть ли у вас тип значения, используя свойство Type.IsValueType и создавать экземпляры с помощью Activator.CreateInstance(Type);

Ответ 2

Да, вы должны использовать Reflection. Но вы уже это делаете, когда используете GetType()

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

var t = x.GetType();
var c = t.GetConstructor(new Type[0]);
if (c != null) ...

Ответ 3

type.GetConstructor(Type.EmptyTypes) != null

завершится с ошибкой struct s. Лучше его продлить:

public static bool HasDefaultConstructor(this Type t)
{
    return t.IsValueType || t.GetConstructor(Type.EmptyTypes) != null;
}

Преуспевает, поскольку даже enum имеет конструктор без параметров без параметров. Также немного ускоряется для типов значений, поскольку вызов отражения не выполняется.

Ответ 4

Это должно работать:

   myClass.GetType().GetConstructors()
                    .All(c=>c.GetParameters().Length == 0)

Ответ 5

В зависимости от вашей ситуации вы также можете использовать ограничение общего типа:

public void DoSomethingWith<T>(T myObject) where T:new() {...}

Вышеуказанное объявление метода ограничивает тип параметра любым объектом, который может быть создан с помощью конструктора без параметров. Преимущество здесь заключается в том, что компилятор поймает любую попытку использовать метод с классом, у которого нет конструктора без параметров, поэтому, если тип известен SOMEWHERE во время компиляции, это будет работать и будет предупреждать вас о проблема раньше.

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

Ответ 6

Да, вы должны использовать отражение.

object myObject = new MyType();
Type type = myObject.GetType();
ConstructorInfo conInfo = type.GetConstructor(new Type[0]);

Ответ 7

Мне нужно было считать конструкторы с только необязательными параметрами такими же, как и конструкторы с истинным параметром. Для этого:

myClass.GetType().GetConstructors()
    .All(c => c.GetParameters().Length == 0 || c.GetParameters().All(p => p.IsOptional))