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

发布于 2024-11-23 23:33:13 字数 1266 浏览 1 评论 0原文

我在一个带有两个重载的类中有一个静态函数。除了一两个参数之外,这两种重载都完全相同。 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
    }

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

ClassABC.Foo("hi there");

这给了我这个: 以下方法或属性之间的调用不明确。我知道为什么会发生这种情况,以及理想的解决方案是什么。但我需要知道 C# 中是否可以做其他事情来解决这个问题。

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

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

  2. 如果没有,我是否可以创建一个函数来处理这两种情况?像这样的事情:

    public static void Foo(string body, string title = "", int x = 0 || object y = null) // 用户应该只能传递其中一个!
    {
        //再说一次,无论如何我都可以处理这个问题
    }
    
  3. 还有其他解决方法可以解决这个问题吗?

编辑:

  1. 我无法重命名这两个函数。

  2. 我无法创建更多重载。不仅仅是这些组合可能。我应该能够编写 Foo(string body, int x) 等。就这样。如果参数超过 10 个,实际上不可能处理所有条件!简而言之,可选参数是必须的。

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:

ClassABC.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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

难理解 2024-11-30 23:33:13

添加一个单独的重载来处理具有一个或两个参数的情况。

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

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

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

} 

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

} 
月野兔 2024-11-30 23:33:13

如果您不确定,请以安全的方式进行。

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

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

有一个带有可变参数的选项。检查每个参数的类型并采取相应的行动:

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

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

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

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

您可以使用 Dictionary 代替新类 FooArguments,其中 key 是参数的名称,value 是论证本身。

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

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.

末骤雨初歇 2024-11-30 23:33:13

提供一个包装器

public static void Foo(string body)

{

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

}

或类似的东西

provide a wrapper

public static void Foo(string body)

{

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

}

or something similiar

夜声 2024-11-30 23:33:13

如何仅实现第二个变体并使用 GetType() 检查作为第三个参数传递的“对象”的实际类型(如果有的话)?然而,这假设跳过第三个参数(x = 0y = null)会导致相同的结果。请注意,这种方法提供的优化选项较少,因为选择必须在运行时进行,而不是编译时(除非编译器能够区分)。

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文