Anthony
Anthony

Reputation: 1714

Instantiate type with string parameter to constructor dynamically

I have the following code:

if (FileType == typeof(ScanUploadFile))
{
    files.Add(new ScanUploadFile(filePath));
}
if (FileType == typeof(FaxFile))
{
    files.Add(new FaxFile(filePath));
}
if (FileType == typeof(BulkScanFile))
{
    files.Add(new BulkScanFile(filePath));
}
if (FileType == typeof(SpecialCategoryFile))
{
    files.Add(new SpecialCategoryFile(filePath));
}

How can I write it without the IF statement?

Upvotes: 1

Views: 1785

Answers (2)

Dyppl
Dyppl

Reputation: 12381

Use GetConstructors method of the Type object and chose the one with single parameter of type string, then invoke it.

Like so:

private ConstructorInfo GetStringConstructor(Type type)
{
    return (from ctor in type.GetConstructors()
            let pars = ctor.GetParameters()
            where pars.Length == 1 && pars[0].ParameterType == typeof(string)
            select ctor).FirstOrDefault();
}

Use it like so:

var ctor = GetStringConstructor(typeof(Test));
if (ctor != null)
    files.Add(ctor.Invoke(new string[] {filePath}));

I made a separate method for extracting the constructor, but if you only intend to use it for actually creating an instance, you can refactor it all in one method that takes string and Type parameters. Pay some attention to proper error handling though.

However, I would consider Factory method pattern here instead of just diving in reflection right away. I can't know if it better suits your needs, but it seems like it probably does.

EDIT: I admit that the CreateInstance is nicer, but my method has the advantage of more control and better error handling.

Upvotes: -1

neontapir
neontapir

Reputation: 4736

Since you are only interested in the constructor, you could use:

 Activator.CreateInstance(FileType, new string[] {filePath});

Activator is defined in the System library.

Upvotes: 8

Related Questions