Check in advance if `System.Activator.CreateInstance (Of T)` fails

I have a type (Human) and I want to know if I can do System.Activator.CreateInstance(Of Human)() . So basically I want to check whether a person has an open constructor without parameters or a public constructor with optional parameters that allow calling New Human without any arguments.

Is it possible to preliminarily check if System.Activator.CreateInstance(Of T) will happen? (I mean, except wrapping the System.Activator.CreateInstance(Of Human)() operator in Try Catch, of course).

I tried this, but it does not work:

 Option Strict On : Option Explicit On Module Test Public Class Human Public Sub New(Optional ByVal a As Integer = 1) End Sub End Class Public Sub Main() Dim c = GetType(Human).GetConstructor(System.Type.EmptyTypes) MsgBox(c Is Nothing) End Sub End Module 
+4
source share
4 answers

To check if the constructor is empty or all parameters are optional:

 var hasEmptyOrDefaultConstr = typeof(Human).GetConstructor(Type.EmptyTypes) != null || typeof(Human).GetConstructors(BindingFlags.Instance | BindingFlags.Public) .Any (x => x.GetParameters().All (p => p.IsOptional)); 
+7
source

You can check and make sure that your Human type has an accessible constructor without parameters. The easiest way is to create a generic method and add a constraint where T : new()

EDIT:

You can manually check the constructor without parameters

 if(typeof(Human).GetType().GetConstructor(Type.EmptyTypes) !=null) { ... } 
+3
source

Note that Activator.CreateInstance<T>() or Activator.CreateInstance(Type) will only work with constructors without parameters. A constructor with optional arguments in this sense is not carefree.

Additional parameters (or arguments) are permitted by the C # compiler on the call site. However, when calling a constructor that uses reflection, the compiler is not involved in this way.

If you use the following code, you will receive a MissingMethodException message in which there is no constructor without parameters:

 namespace ConsoleApplication1 { public class Foo { public Foo(int optional = 42) { } } class Program { static void Main(string[] args) { Activator.CreateInstance<Foo>(); // causes MissingMethodException } } } 

In other words, the optional arguments are a compiler, not a CLR.

For more information on β€œcorner cases with extra arguments,” see this recent Eric Lippert blog series:

http://ericlippert.com/2011/05/09/optional-argument-corner-cases-part-one/

Having said that, you can somehow reproduce the desired behavior, using some reflection and manually creating the required parameters to call the constructor. The compiler will place some attributes inside the assembly that you can use for this purpose, I think.

Example:

 public class Foo { public Foo([Optional, DefaultParameterValue(5)] int optional) { Console.WriteLine("Constructed"); } } 
+3
source

I created a quick console application that uses reflection to test constructors without parameters for types. That's what you need?

 using System; using System.Linq; namespace ConsoleApplication { public class HasPublicParameterlessContructorClass { } public class DoesntHavePublicParameterlessContructorClass { private int someField; public DoesntHavePublicParameterlessContructorClass(int someParameter) { someField = someParameter; } } class Program { public static bool HasPublicParameterlessContructor(Type t) { return t.GetConstructors().Any(constructorInfo => constructorInfo.GetParameters().Length == 0); } static void Main() { Console.WriteLine(HasPublicParameterlessContructor(typeof(HasPublicParameterlessContructorClass))); Console.WriteLine(HasPublicParameterlessContructor(typeof(DoesntHavePublicParameterlessContructorClass))); } } } 
+1
source

All Articles