C# 重载是向同一函数添加不同参数的唯一方法吗?

C# 重载是向同一函数添加不同参数的唯一方法吗?,c#,.net,C#,.net,我有两个函数,做同样的精确操作;因为基础API有一个重载函数,可以接受字符串或int 因为我正在使用这个函数,所以我需要用字符串或int来调用这个函数。重载是唯一的方法吗?我在函数签名旁边复制代码;这似乎是对代码的浪费 public void taketwo(int value1, int value2) { // Other operations happen here baseAPI.getvalues(value1, value2); } public void take

我有两个函数,做同样的精确操作;因为基础API有一个重载函数,可以接受字符串或int

因为我正在使用这个函数,所以我需要用字符串或int来调用这个函数。重载是唯一的方法吗?我在函数签名旁边复制代码;这似乎是对代码的浪费

public void taketwo(int value1, int value2)
{
    // Other operations happen here
    baseAPI.getvalues(value1, value2);
}

public void taketwo(string val1_str, string val2_str)
{
    // Other operations happen here
    baseAPI.getvalues(val1_str, val2_str);
}

我记得一些关于泛型函数的事情;但我不确定这是否适用于本案;我过去从未使用过它们,在深入研究之前,我认为值得先询问一下。

好吧,从技术上讲,您可以将所有这些参数组合到一个方法中,并将它们设置为默认参数
null

public void taketwo(int? value1 = null, int? value2 = null, 
                    string val1_str = null, string val2_str = null)
{
    if (value1 != null)
       baseAPI.getvalues(value1.Value, value2.Value);
    else if (val1_str != null)
       baseAPI.getvalues(val1_str, val2_str);
}
因此,您可以将其称为
taketwo(1,2)
以及
taketwo(val1_str:“str1”,val2_str:“str2”)
,因为所有参数都有默认值


它是否更方便-这取决于你。就我个人而言,我更喜欢方法重载,而不是将所有可能的参数组合成一个方法。

从技术上讲,您可以将所有这些参数组合成一个方法,并将它们设置为默认参数
null

public void taketwo(int? value1 = null, int? value2 = null, 
                    string val1_str = null, string val2_str = null)
{
    if (value1 != null)
       baseAPI.getvalues(value1.Value, value2.Value);
    else if (val1_str != null)
       baseAPI.getvalues(val1_str, val2_str);
}
因此,您可以将其称为
taketwo(1,2)
以及
taketwo(val1_str:“str1”,val2_str:“str2”)
,因为所有参数都有默认值


它是否更方便-这取决于你。就我个人而言,我更喜欢方法重载,而不是将所有可能的参数组合到一个方法中。

您可以将重复的代码(用
//标记)放入自己的方法中(如果适用)。显然,如果这个重复的代码不使用传入的参数,这只会起作用


这里不能使用泛型方法,因为泛型是编译时特性,而不是运行时特性。 您可以使用
dynamic
。在这种情况下,重载解析将在运行时发生。但是它的缺点是,您也可以传递
double
Uri
对象,并且只有在运行时才会得到异常,因为
baseAPI.getvalues
不存在这样的重载

代码:


如果适用,您可以将重复的代码(标记为
//其他操作在此处发生)放入它自己的方法中。显然,如果这个重复的代码不使用传入的参数,这只会起作用


这里不能使用泛型方法,因为泛型是编译时特性,而不是运行时特性。 您可以使用
dynamic
。在这种情况下,重载解析将在运行时发生。但是它的缺点是,您也可以传递
double
Uri
对象,并且只有在运行时才会得到异常,因为
baseAPI.getvalues
不存在这样的重载

代码:

您可以在此处使用动态键入:

// I don't recommend you do this - see later
public void TakeTwo(dynamic value1, dynamic value2)
{
    baseAPI.GetValues(value1, value2);
}
调用
GetValues
的重载解析将在执行时执行

然而:

  • 没有编译时检查对
    TakeTwo
    的调用是否有效
  • 效率较低(这可能重要,也可能不重要;在大多数情况下,第一点更重要)
您谈到了复制代码,但在示例中,您展示的所有代码都是方法调用。如果该方法中有其他真正常见的代码,我建议将该常见代码提取出来,并在两个重载中调用它:

public void TakeTwo(int value1, int value2)
{
    CommonCode();
    baseAPI.GetValues(value1, value2);
}

public void TakeTwo(string value1, string value2)
{
    CommonCode();
    baseAPI.GetValues(value1, value2);
}

private void CommonCode()
{
    // Things you want to do in both methods
}
您可以在此处使用动态键入:

// I don't recommend you do this - see later
public void TakeTwo(dynamic value1, dynamic value2)
{
    baseAPI.GetValues(value1, value2);
}
调用
GetValues
的重载解析将在执行时执行

然而:

  • 没有编译时检查对
    TakeTwo
    的调用是否有效
  • 效率较低(这可能重要,也可能不重要;在大多数情况下,第一点更重要)
您谈到了复制代码,但在示例中,您展示的所有代码都是方法调用。如果该方法中有其他真正常见的代码,我建议将该常见代码提取出来,并在两个重载中调用它:

public void TakeTwo(int value1, int value2)
{
    CommonCode();
    baseAPI.GetValues(value1, value2);
}

public void TakeTwo(string value1, string value2)
{
    CommonCode();
    baseAPI.GetValues(value1, value2);
}

private void CommonCode()
{
    // Things you want to do in both methods
}

根据您的
baseAPI
设计,您可以使用泛型:

public void taketwo<T>(T val1, T val2)
{
    // Other operations happen here
    baseAPI.getvalues<T>(val1, val2);
}
public void taketwo(T val1,T val2)
{
//其他操作在这里发生
baseAPI.getvalues(val1,val2);
}

但这首先需要将
baseAPI.getvalues
设置为泛型。

根据
baseAPI
设计,您可以使用泛型:

public void taketwo<T>(T val1, T val2)
{
    // Other operations happen here
    baseAPI.getvalues<T>(val1, val2);
}
public void taketwo(T val1,T val2)
{
//其他操作在这里发生
baseAPI.getvalues(val1,val2);
}

但这首先需要使您的
baseAPI.getvalues
通用化。

您可以尝试接收一个对象(向上转换),这意味着他将能够发送一个字符串或int,然后使用简单的if-else,您可以基于该对象的值将其发送到正确的函数

public void taketwo(Object value1, Object value2) { 

// Other operations happen here 

If (check if value1 is a number) {
  baseAPI.getvalues(value1, value2); 
} else {
  baseAPI.getvalues(val1_str, val2_str);
}

您可以尝试接收一个对象(向上转换),这意味着他将能够发送字符串或int,然后使用简单的if-else,您可以根据该对象的值将其发送到正确的函数

public void taketwo(Object value1, Object value2) { 

// Other operations happen here 

If (check if value1 is a number) {
  baseAPI.getvalues(value1, value2); 
} else {
  baseAPI.getvalues(val1_str, val2_str);
}

int和string参数代表不同的概念吗?如果没有,那么您只能通过从“int重载”调用“string重载”来对实现编码一次

public void taketwo(int value1, int value2)
{
    taketwo(value1.ToString(), value2.ToString())
}

public void taketwo(string val1_str, string val2_str)
{
    // Other operations happen here
    baseAPI.getvalues(val1_str, val2_str);
}

假设方法中不止一个API调用,这是有意义的。

int和string参数代表不同的概念吗?如果没有,那么您只能通过从“int重载”调用“string重载”来对实现编码一次

public void taketwo(int value1, int value2)
{
    taketwo(value1.ToString(), value2.ToString())
}

public void taketwo(string val1_str, string val2_str)
{
    // Other operations happen here
    baseAPI.getvalues(val1_str, val2_str);
}

假设方法中不止一个API调用,这是有意义的。

下面是我处理上述场景的代码版本。在我看来,传递泛型类而不是传递多个参数是有意义的