0

I have an assembly called 'FileParser' which contains the class 'FileAutoSys' which conforms to the interface 'IFile'.

namespace FileParser
{
    class FileAutoSys : IFile
    {
        public FileAutoSys(ref string[] args)
        {
            ...
        }
        public FileAutoSys(){}
        public void SetValues(ref string[] args)
        {
            *[same code as in the non-default constructor]*
        }
}

I am trying to create an instance of FileAutoSys using Activator.CreateInstance but I am having problems passing args into its constructor.

I can create an instance and set its state using a two-step procedure:

IFile file = (IFile)Activator.CreateInstance(Type.GetType("FileParser.File" + args[0]));
file.SetValues(ref args);

where args[0] is the string 'AutoSys'.

But I don't know how to do it all in one step. I've Googled but I can't find any clear examples of how it's done. MSDN suggests I use the overload:

Activator.CreateInstance(Type, Object[])

but, unhelpfully, it doesn't give any examples and my lack of C# knowledge makes it confusing.

I was hoping someone could explain to me how I should use the abovementioned overload in the context of my example. I am not asking for someone to do it for me as I would like to understand what it is that I should be doing.

PingPing
  • 899
  • 6
  • 15
  • 28
  • 4
    `(IFile)Activator.CreateInstance(Type.GetType("FileParser.File" + args[0]), args)`? – antonijn Mar 25 '13 at 11:57
  • Just pass in the values as an array of `object[]`: http://stackoverflow.com/a/6410370/263681 – Grant Thomas Mar 25 '13 at 11:59
  • possible duplicate of [Generics in C# - how can I create an instance of a variable type with an argument?](http://stackoverflow.com/questions/6410340/generics-in-c-sharp-how-can-i-create-an-instance-of-a-variable-type-with-an-ar) – Grant Thomas Mar 25 '13 at 11:59
  • I'm skeptical of my comment though, I don't know whether that will work with a `ref` parameter. – antonijn Mar 25 '13 at 12:01
  • Why on Earth is this important? Always favor readability. – Hans Passant Mar 25 '13 at 12:01
  • 2
    Any particular reason you have declared args as ref? – Botz3000 Mar 25 '13 at 12:01
  • @HansPassant Well, this is more of a question about the .NET framework (not functionality of this particular application), so I can see why the OP is asking it. – antonijn Mar 25 '13 at 12:02
  • @Grant Thomas - I don't think it is a duplicate. There are no generic parameters here. – PeteGO Mar 25 '13 at 12:04
  • @PeteGO The generics are irrelevant, `T` is equivalent to the explicit type. Otherwise it is precisely the same. – Grant Thomas Mar 25 '13 at 12:05
  • I've declared args as ref because I thought it would save space and execution time. Is this not the right way to do things? – PingPing Mar 25 '13 at 12:17
  • `ref` in a constructor - it's not recommended (and pretty much useless) - see this one http://stackoverflow.com/questions/5261174/c-keep-ref-parameter-from-constructor-in-class – NSGaga-mostly-inactive Mar 25 '13 at 12:18
  • @PingPing No, when using reference types (your array is one, as well as `string`, and every type declared with the `class` keyword), you always pass a reference to the actual object, so there is no copying involved. The only time `ref` would be useful is if you want to reassign the original variable, which is probably not what you want. In most cases, you don't need `ref` or `out` parameters. – Botz3000 Mar 25 '13 at 12:37
  • Possible duplicate of [How to Pass Parameters to Activator.CreateInstance()](http://stackoverflow.com/questions/2451336/how-to-pass-parameters-to-activator-createinstancet) – Michael Freidgeim Aug 04 '16 at 05:13

3 Answers3

5

Just pass them in as the 2nd argument.

IFile file = (IFile)Activator.CreateInstance(
    Type.GetType("FileParser.File" + args[0]), new object[] { args });

EDIT: Wrapped the 2nd argument in an array as this is the parameter type expected, as well as the argument type on Activator.CreateInstance, I think this is why it is confusing.

PeteGO
  • 5,597
  • 3
  • 39
  • 70
3

Try this:

class CreateMe {
    public CreateMe(ref string[] args) {
    }
}

class Program {
    static void Main(string[] args) {
        var createMe = Activator.CreateInstance(typeof(CreateMe), new object[] { args });
    }
}
Paolo Tedesco
  • 55,237
  • 33
  • 144
  • 193
  • You're passing an array with a single element which is the array of arguments. – Grant Thomas Mar 25 '13 at 12:02
  • You're correct, it was my mistake on missing how the constructor was defined. – Grant Thomas Mar 25 '13 at 12:18
  • @GrantThomas: I think the problem actually comes from the fact that the "params object[]" argument of CreateInstance turns the string[] args into several strings, so for example if you have an array with 2 strings it searches for a constructor with 2 string arguments... – Paolo Tedesco Mar 25 '13 at 12:23
1
IFile file = (IFile)Activator.CreateInstance(Type.GetType("FileParser.File" + args[0]), new object[]{args});
IS4
  • 11,945
  • 2
  • 47
  • 86