Calling Constructors in C# Using Reflection

Reflection can be used in C# to invoke a class’ constructor. This is useful when you don’t know the type of the class that you want to instantiate until runtime.
As usual, there are various options open to you depending on your requirements.

Invoking the Default (Parameterless) Constructor

When You Can Pass the Required Type as a Generic Parameter

Under these circumstances, you don’t need to use reflection at all:
[code language=”C#”]
T Instantiate() where T : new()
{
return new T();
}
[/code]
Alternatively, you can call the generic version of Activator.CreateInstance:
[code language=”C#”]
ObjectType instance = Activator.CreateInstance();
[/code]

When You Know the Required Type

You can instantiate using either the type itself:
[code language=”C#”]
ObjectType instance = (ObjectType)Activator.CreateInstance(objectType);
[/code]
Or the type’s name:
[code language=”C#”]
ObjectType instance = (ObjectType)Activator.CreateInstance(“MyNamespace.ObjectType, MyAssembly”);
[/code]

When You Need a Reference to the Default Constructor

This is useful if you want to call the constructor later.
[code language=”C#”]
var constructor = type.GetConstructor(Type.EmptyTypes);

ObjectType instance = (ObjectType)constructor.Invoke(null);
[/code]

Invoking a Parameterized Constructor

If you want to get a reference to a constructor that has, for example, two parameters, the first of which is a long and the second an int:
[code language=”C#”]
// We need the constructor with the following signature:
var argTypes = new[]
{
typeof (long),
typeof (int)
};
ConstructorInfo constructor = ObjectType.GetConstructor(argTypes);
[/code]
This constructor can then be invoked like this:
[code language=”C#”]
var argValues = new object[] { lngFirstParameter, intSecondParameter };
ObjectType instance = (ObjectType) constructor .Invoke(argValues);
[/code]

Getting Information About Constructor Parameters

The following method will write out the parameters of type ObjectType:
[code language=”C#”]
public void PrintParameters()
{
var ctors = typeof(ObjectType).GetConstructors();
// Assuming class ObjectType has only one constructor:
var ctor = ctors[0];
foreach (var param in ctor.GetParameters())
{
Console.WriteLine(string.Format(“Parameter {0} is named {1} and is of type {2}”,param.Position, param.Name, param.ParameterType));
}
}
[/code]

References

The C# Null Coalescing Operator

Introduction

A the ?? operator is a binary operator that is used to simplify checking for null values.

If the left operand is not null, it returns the left operand, otherwise it returns the right operand.

For example:

This means that:

Is equivalent to:

And is even shorter than:

The ?? operator is right-associative, which means that it is evaluated from right to left. This means that:

is evaluated as:

Rules

  • Arguments can be reference types or nullable types.
  • If both arguments are constant, the result is not considered to be a constant.
  • Both arguments must be of the same type.

Uses

Assigning a Non-Nullable Type from a Nullable Type

int result;
int a? = null;
result = a ?? 1; // Assigns 1 to result.

Lazily Instantiated Properties

Avoiding Double Evaluation
Chaining

References

C#: How to Clone a Generic List

Found on StackOverflow, this is a tidy example of an generic extension method that uses LINQ:

Exception Passing DBNull.Value to a Varbinary Using Parameters.AddWithValue

In .Net it seems reasonable to try to pass a NULL to a SQL Server stored procedure using the following syntax (C#):
[sourcecode language=”csharp”]
myCommand.Parameters.AddWithValue(“@MyParameter”, DBNull.Value);
[/sourcecode]
Unfortunately, if the sproc is expecting a parameter of type Varbinary(max), the following exception will be thrown:
Implicit conversion from data type nvarchar to varbinary(max) is not allowed. Use the CONVERT function to run this query.
This appears to be a bug in the .Net SqlDataAdapter.
The work-around is to be explicit about the type of data you are passing:
[sourcecode language=”csharp”]
myCommand.Parameters.Add(“@MyParameter”, SqlDbType.VarBinary, -1);
myCommand.Parameters[“@MyParameter”].Value = DBNull.Value;
[/sourcecode]
My thanks go to dnagelhout and Matt Neerincx for their invaluable posts on this subject.