简体   繁体   English

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

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

I have a static function in a class with two overloads.我在 class 中有两个过载的 static function。 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. string body是我的 function 中唯一必要的参数,你可以看到,rest 是可选参数。 But parameters object y and int x shouldn't come together.但是参数object yint x不应该放在一起。 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:现在,当我想从其他类中调用此 static function 时,由于string body是唯一必需的参数,因此我有时会尝试编写:

ClassABC.Foo("hi there");

Which gives me this: The call is ambiguous between the following methods or properties .这给了我这个: 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.但我需要知道在 C# 中是否可以做任何其他事情来解决这个问题。

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 .显然,编译器在选择 function 到 go 时感到困惑,但我不介意编译器会考虑两者在没有int xobject 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?如果没有,无论如何我可以创建一个 function 来处理这两种情况吗? 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.我应该能够写Foo(string body, int x)等。所以去。 Its virtually impossible to handle all conditions if parameters are more than say, 10., In short.如果参数超过 10 个,则几乎不可能处理所有条件。简而言之。 optional parameters are a must.可选参数是必须的。

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.编辑:既然你提到可能有 10 个左右的参数,你需要一个更通用的解决方案。

There is an option with variable arguments.有一个带有变量 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.如果两个 arguments 具有相同的类型但不同的功能(字符串标题,例如字符串作者),那么您需要其他东西。 You can have a class that has all the arguments as members.您可以拥有一个 class,其中所有 arguments 作为成员。 User should fill the object of that class and pass that object as only argument:用户应填写 class 的 object 并将 object 作为唯一参数传递:

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.而不是 new class FooArguments 您可以使用Dictionary<string,object>其中 key 是参数的名称,而 value 是参数本身。

If the function is called with inappropriate combination of arguments then just throw an exception.如果 function 被不适当的 arguments 组合调用,那么只需抛出一个异常。

Add a separate overload to handle the cases with one or two arguments.添加一个单独的重载来处理一个或两个 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:如果您需要处理 arguments 的任意组合,那么也许是时候将您的可选 arguments 分组到他们自己的 class 中了:

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

} 

provide a wrapper提供一个包装器

public static void Foo(string body)公共 static void Foo(字符串主体)

{ {

   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() ?如何仅实现第二个变体并使用GetType()检查作为第三个参数(如果有的话)传递的“对象”的实际类型? This however assumes skipping the third parameter ( x = 0 or y = null ) would lead to the same results.然而,这假设跳过第三个参数( x = 0y = null )将导致相同的结果。 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).请注意,这种方法提供的优化选项较少,因为选择必须在运行时进行 - 而不是编译时(除非编译器能够区分)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何为T [],T [] []编写重载的泛型扩展方法而没有歧义? - How to write overloaded generic extension methods for T[], T[][] without ambiguity? 使用不同参数重载方法对.NET的误解(Call Ambiguous) - Misunderstanding of .NET on overloaded methods with different parameters (Call Ambiguous) 重载方法是否可以转换它们的参数然后调用它们的原始方法? - Is it acceptable for overloaded methods to cast their parameters and then call their original method? 重载方法的泛型调用 - Generic call of overloaded methods 如何在方法中放置可选参数? - How do I put optional parameters in methods? 如何使用mono.cecil注入具有可选参数的函数调用? - how to use mono.cecil to inject a function call having optional parameters? 如何重构重载方法 - How to refactor overloaded methods 重载方法可以在不强制使用C#的情况下与不同类型一起使用吗? - Can overloaded methods work with different types without having to cast in c#? 在C#4中,如何在具有重载构造函数的父类的子类中具有带可选参数的构造函数? - In C# 4, how can I have constructors with optional parameters in a subclass of a parent with an overloaded constructor? 设计8个重载方法的最佳方法,结合4个参数 - Best approach to design 8 overloaded methods with combination of 4 parameters
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM