如何调用具有可选参数的重载方法而没有编译器的歧义?

naw*_*fal 3 c# overloading optional-parameters argument-passing

我在一个有两个重载的类中有一个静态函数.除了一个或两个参数外,两个重载都完全相同.string body是我可以看到的函数中唯一必需的参数,其余是可选参数.但参数object yint x不应该走到一起.所以我不得不写下两个重载.我提供了一个示例代码:

    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
    }
Run Code Online (Sandbox Code Playgroud)

现在当我想从其他类调用这个静态函数时,因为string body是唯一必需的参数,我有时会尝试写:

ClassABC.Foo("hi there");
Run Code Online (Sandbox Code Playgroud)

这给了我这个:The call is ambiguous between the following methods or properties.我知道为什么会发生这种情况,理想情况下解决方案是什么.但是我需要知道在C#中是否还可以做任何其他事情来解决这个问题.

显然,编译器对于选择要使用的函数感到困惑,但是我不介意编译器的任何考虑都考虑到两者都是相同的没有int xobject y.基本上三个问题:

  1. 有没有告诉编译器"采取任何"(几乎不可能的任务,但仍然让我知道)?

  2. 如果没有,无论如何我是否可以创建一个单独的功能来处理这两种情况?像这样的东西:

    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
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 还有其他解决方法吗?

编辑:

  1. 我无法重命名这两个功能.

  2. 我不能创建更多的重载.这些组合不仅仅是可能的.我应该能够写Foo(string body, int x)等等.如果参数超过10,则几乎不可能处理所有条件.简而言之,可选参数是必须的.

Dia*_*cus 5

如果您不确定这样做是否安全.

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)
{
}
Run Code Online (Sandbox Code Playgroud)

编辑:既然你提到可能有10个左右的参数你需要一个更通用的解决方案.

有一个带变量参数的选项.检查每个参数的类型并采取相应措施:

public static void Foo(string body, param object[] the_rest_of_arguments)
{
}
Run Code Online (Sandbox Code Playgroud)

如果两个参数具有相同的类型但功能不同(字符串标题,比如字符串作者),那么您还需要其他参数.您可以拥有一个将所有参数都作为成员的类.用户应该填充该类的对象并将该对象作为唯一参数传递:

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

public static void Foo(string body, FooArguments the_rest_of_arguments)
{
}
Run Code Online (Sandbox Code Playgroud)

您可以使用Dictionary<string,object>key作为参数名称,而不是新类FooArguments ,value是参数本身.

如果使用不适当的参数组合调用函数,则只抛出异常.


ham*_*mar 5

添加一个单独的重载来处理具有一个或两个参数的案例.

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)
{
}
Run Code Online (Sandbox Code Playgroud)

如果您需要处理任意参数组合,那么可能是时候将可选参数分组到自己的类中了:

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)
{

} 
Run Code Online (Sandbox Code Playgroud)