-1

I have the following problem:

public class MyType
{
    public void method(int a, params object[] p){} 
    public void MyType()
    {
        method(5);
    }
}

When I use a constructor everything is fine but when I try to use Activator.CreateInstance(MyType);

void Factory()
{
    string componentPath = "MyType.dll";
    Assembly component = Assembly.LoadFrom(componentPath);
    Type myType= component.GetType("MyType");
    Activator.CreateInstance(myType);
}

it fails with exception MyType.method(int32) is not found. Important to notice that before I added params object[] p to method everything worked fine.

Thank You.

Sergey Kucher
  • 4,140
  • 5
  • 29
  • 47

2 Answers2

3

If you use methods with optional parameters or methods with params to pass a variable number of parameters, what you're doing is telling the compiler that when you CALL that method, will it please insert the necessary parameters for you? Optional parameters and params arrays are inserted in the calling code, not the called code. (See one of Eric Lipperts blog posts on optional parameters for some elaboration).

You're not using the C# compiler, and the Reflection API does not insert those parameters for you. For example, you can test this not just by reflection, but also by using two assemblies: Assembly A declares method(int X); it is compiled and the dll is referenced by assembly B. This assembly B contains a call to method(42). This works fine! Now, if you recompile assembly A and change the signature to method(int X, object bla=null) or method(int X, params object[] blas), then assembly B stops working - it contains an invalid call. Even so, the source code to assembly B is still OK - you just need to recompile.

Reflection simply happens not to do any of the optional parameter magic for you. It could, certainly - but it doesn't. While reflection doesn't support this, the DLR does, which brings me to the following...

Workaround: Try using the C# keyword dynamic, if possible (which for constructors, it isn't AFAIK) - that attempts to emulate C# calling conventions more closely and supports stuff like optional and named parameters. You may need to change the way your API is set up, however to use methods rather than constructors. It's hard to give more precise advice without seeing actual code.

Alternatively: You may be trying to load plugins, by the looks of it. .NET has some premade infrastructure to help you with this: Add-ins and Extensibility, which may make your task easier.

(Note: your example code is incomplete - I'm making a slight guess that method is in reality a constructor, but you should really post the actual code or at least a snippet that actually fails).

Eamon Nerbonne
  • 47,023
  • 20
  • 101
  • 166
  • Thank you very much your answer was great ! I am sorry that i could not define my question properly. – Sergey Kucher May 25 '11 at 08:32
  • I know that you've accepted this as an answer, so you've probably solved your problem, but could you still fix the code example? That would make your question useful to others, and I bet Heandel will remove the downvote... – Eamon Nerbonne May 25 '11 at 08:36
0

This won't work because you have to pass at least 2 parameters in your call to method(). The params modifier doesn't mean "optional".

Roy Dictus
  • 32,551
  • 8
  • 60
  • 76
  • And even optional parameters aren't optional at the call site: http://blogs.msdn.com/b/ericlippert/archive/2011/05/16/optional-argument-corner-cases-part-three.aspx – Eamon Nerbonne May 25 '11 at 08:08
  • 2
    @Heandel: If you're calling from C# code - sure. But he's using reflection; and this is a method that requires an array of objects as second parameter. The *intent* is to allow simple syntactic sugar in which the array contents can look like parameters, but the *implementation* is simply an array. It's not optional, and it's not passed "automatically" - the compiler inserts parameter for you. – Eamon Nerbonne May 25 '11 at 08:11
  • @Eamon Nerbonne: I think you have to post your comment as answer. – Egor4eg May 25 '11 at 08:15
  • @Eamon Nerbonne: should not the compiler add the missing parameter when it compiles the MyType class? – Sergey Kucher May 25 '11 at 08:20
  • It adds the missing parameter when it compiles your *call* to the method, not when it compiles the method itself. – Eamon Nerbonne May 25 '11 at 08:41