Я хотел бы проверить, не знает ли тип во время выполнения конструктор без параметров. Класс 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))