开发者

How to call overloaded methods having optional parameters without ambiguity for compiler?

I have a static function in a class with two overloads. Both the overloads are quite the same with the exception of one or two parameters. string body is the only necessary parameter in my function which you can see, rest are optional parameters. But parameters object y and int x shouldn't come together. So i had to write two overloads as below. I provide a sample code:

    public static void Foo(string body, string caption = "", int x = 0)
    {
        //leave it to me
    }

    public static void Foo(string body, string caption = "", object y = null)
    {
        //leave it to me
    }

Now when I want to call this static function from other classes, since string body is the only required parameter, I try to write at times:

ClassAB开发者_JAVA百科C.Foo("hi there");

Which gives me this: The call is ambiguous between the following methods or properties. I know why this happens, and what ideally the solution is. But I need to know if anything else could be done in C# to tackle this.

Obviously, the compiler is confused as to choose which function to go for, but I wouldnt mind the compiler going for any considering both are the same without int x and object y. Three questions basically:

  1. Is there anyway to tell the compiler "take any" (almost impossible task, but still let me know)?

  2. If not, is there anyway I can create a single function to handle both cases? Something like this:

    public static void Foo(string body, string caption = "", int x = 0 || object y = null) // the user should be able to pass only either of them!
    {
        //again, I can handle this no matter what
    }
    
  3. Any other workarounds to solve this?

EDIT:

  1. I can not rename the two functions.

  2. I can not create more overloads. It's not just these combinations possible. I should be able to write Foo(string body, int x) etc. So goes. Its virtually impossible to handle all conditions if parameters are more than say, 10!. In short, optional parameters are a must.


Add a separate overload to handle the cases with one or two arguments.

public static void Foo(string body, string caption = "")
{
} 

public static void Foo(string body, string caption, int x)
{
}

public static void Foo(string body, string caption, object y)
{
}

If you need to handle arbitrary combinations of arguments, then perhaps it's time to group your optional arguments into a class of their own:

public sealed class Options
{
    public string Caption { get; set; }
    public int X { get; set; }
    public object Y { get; set; }
}

public static void Foo(string body, Options options)
{

} 


If you're not sure do it the safe way.

public static void Foo(string body)
{
}

public static void Foo(string body, string caption)
{
}

public static void Foo(string body, string caption, int x)
{
}

public static void Foo(string body, string caption, object y)
{
}

EDIT: Since you mentioned that there may be 10 or so parameters you need a more general solution.

There is an option with variable arguments. Check the type of each argument and act accordingly:

public static void Foo(string body, param object[] the_rest_of_arguments)
{
}

If two arguments have the same type but different functionality (string caption and, say, string author) then you need something else. You can have a class that has all the arguments as members. User should fill the object of that class and pass that object as only argument:

public class FooArguments
{
    public string caption;
    public int x;
    public object y;
}

public static void Foo(string body, FooArguments the_rest_of_arguments)
{
}

Instead of new class FooArguments you can have Dictionary<string,object> where key is the name of the argument, and value is the the argument itself.

If the function is called with inappropriate combination of arguments then just throw an exception.


provide a wrapper

public static void Foo(string body)

{

   public static void Foo(string body,  "", null);
  //leave it to me

}

or something similiar


How about implementing the second variant only and checking the actual type of the 'object' passed as third parameter (if any at all) using GetType()? This however assumes skipping the third parameter (x = 0 or y = null) would lead to the same results. Note that this approach offers less options for optimization as the selection has to happen at runtime - not compile time (unless the compiler is able to differentiate that).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜