Coder
Coder

Reputation: 455

How to create in C# a method taking a method as parameter having an undeterminded numbers of parameters?

I am new to C# and have a question. I am not sure if this question or similar to it was asked before however, I couldn't find a clear solution. I have created a method in C# and its parameter is a generic method:

public void MyMethod (some_generic_method)

That "some_generic_method" may have different numbers of parameters with homogeneous datatypes. How should I create the signature of "MyMethod"?

Edit: I will try to explain as clearly as possible why the asked solution is needed. I am making a testing library in C# and the library includes a method similar to "MyMethod".

Imagine:

I hope this explanation makes the question clearer.

Thanks.

Upvotes: 2

Views: 199

Answers (2)

user12031933
user12031933

Reputation:

Consideration

There is no possibility to call a method without knowing its signature, as I know.

And in C# that is not like Javascript or Python or Ruby for example, a signature is static, definitively defined after compiled, so immutable.

Even using reflexion on an object as parameter, you will have the same problem to manage parameters of this unknown method having unknow parameters of unknown types.

C# is a strongly-typed language, a compiled language, even using dynamics.

C# Generics don't mean to not known types and signature, on the contrary, and they are not C++ Templates even these are ancestors.

Using params for parameters

https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/params

public delegate void ParameterizedActionWithParams(params object[] parameters);

public void MyAction(ParameterizedActionWithParams action, params object[] parameters)
{
  if ( action != null )
    action(parameters);
  else
    ManageArgumentNullException();
}

Using a list of objects

public delegate void ParameterizedActionWithList(List<object> parameters);

public void MyAction(ParameterizedActionWithList action, List<object> parameters)
{
  if ( action != null )
    action(parameters);
  else
    ManageArgumentNullException();
}

Limitations

You can't have strong typed arguments.

And if you need functions too there is a problem if the returned parameter can vary and you only can do:

public delegate object ParameterizedFuncWithParams(params object[] parameters);

public delegate object ParameterizedFuncWithList(List<object> parameters);

So you need to create these variants:

public object MyFunc(ParameterizedFuncWithParams func, params object[] parameters)
{
  if ( func != null )
    return func(parameters);
  else
    ManageArgumentNullException();
}

public object MyFunc(ParameterizedFuncWithList func, List<object> parameters)
{
  if ( func != null )
    return func(parameters);
  else
    ManageArgumentNullException();
}

Upvotes: 2

Joel Coehoorn
Joel Coehoorn

Reputation: 415600

That "some_generic_method" may have different numbers of parameters with homogeneous datatypes.

The "homogenous datatypes" limitation helps a lot. We can define our new method with a single type argument:

public void MyMethod<T>(...)

Unfortunately, we can't quite get all the way there with a single method. We'll need an overload for each number of supported type arguments:

public void MyMethod<T>(Func<T> arg) { ... }
public void MyMethod<T>(Func<T,T> arg) { ... }
public void MyMethod<T>(Func<T,T,T> arg) { ... } 
// etc

If you look at the framework source, this is what the platform designers themselves had to do for things like delegates, Tuples, and params arguments.

But I wonder if you could adjust to do something like one of these:

public void MyMethod<T>(Func<IEnumerable<T>,T> arg) { ... }
public void MyMethod<T>(Func<T[],T> arg) { ... } 

Upvotes: 1

Related Questions