繁体   English   中英

在方法签名中使用params []是一个坏主意

[英]Is it a bad idea to use params [] in method signature

考虑以下课程

public class PlanetKrypton
 {
  public static void CallSuperManforHelp(string helpMessage, params object[] kryptonParams)
  {
   Console.WriteLine(String.Format(helpMessage,kryptonParams));
  }

  public static void CallSuperManforHelp(string helpMessage ,string sender,string senderZipCode)
  {
   Console.WriteLine("{0} from {1}. I am {2}", helpMessage, sender, senderZipCode);
  }
 }

 public class ConsoleMan
 {
  public static void Main(string[] args)
  {
   string helpMessage = "I have a flat tire";
   string sender = "Jerry";
   int wrongZipType = 12345;


   PlanetKrypton.CallSuperManforHelp(helpMessage, sender, wrongZipType);
   PlanetKrypton.CallSuperManforHelp(helpMessage);
  }
 }

现在,如果我在第一个方法中有一个更强类型的方法签名,那么这两个方法调用都会产生编译时错误。

在方法签名中使用params是否有“最佳实践”?

编辑:我正在制作一个社区维基

我自己很少看到它的需要。

如果我的函数可能需要一个项集合,我就是这样做的:ICollection <>或IEnumerable <>,可能有一个重载,在这种特殊情况下需要一个T.

如果函数本质上更实用(例如,我有一个通用的多字段HashCode生成函数),其中params似乎适合,我仍然会为特定情况提供相当多的重载,例如1 arg,2 args,3 args ...有时候是5 args或10 args。 然后我将添加一个带有参数的全部。 我这样做是因为用params隐含了数组对象。

嗯,显而易见的是编译时错误比运行时错误更好。 但是,有时必须优先考虑灵活,可用的API。 我会说一般来说你应该只使用Object的数组,它缺乏编译时类型的安全性,如果你确定没有更多的静态方法可以实现你想要的东西,那么它们有时会效率低下。

我会避免使用params []对象。 我要做的是创建一个类,在第二个重载中封装三个字符串:

public class HelpStuff
{
   public string Message{get;set;}
   public string Help{get;set;}
   public string ZipCode{get;set;}
}

然后有两个这样的重载:

  public static void CallSuperManforHelp(string helpMessage, params string[] kryptonParams)
    {
            //do work
    }

    public static void CallSuperManforHelp(HelpStuff helpStuff)
    {
           //do work
    }

如果你有这个方法:

    public static void CallSuperManforHelp(string helpMessage, params object[] kryptonParams) { ... }

你可以用这些代码来冷却它:

CallSuperManforHelp("please help");
CallSuperManforHelp("please help", (object[])null);

这些呼叫是等效的。 因此,如果您重载“CallSuperManforHelp”,您应该考虑调用这些方法的召集。

它很少需要,但有时很有用 - 所以我不会说这是避免它的最佳做法。 尽量避免模棱两可。

String.Format当然是规范的例子,大多数情况下我使用params,它传递给String.Format(例如一个日志记录方法)。

该框架的另一个例子是DataRowCollection.Add :能够在不首先构建对象数组的情况下添加字段值非常有用:

    DataTable myDataTable;
    ...
    for(...)
    {
        myDataTable.Rows.Add(col1Value, col2Value, col3Value);
    }

我不会以这种方式混合params / regular重载 - 我通常只使用params来添加一个覆盖,它需要额外的 (在编译时未知)参数。

例如,一种常规方法,然后采用另外一种方法:

public static void CallSuperManforHelp(string helpMessage);
public static void CallSuperManforHelp(string helpMessage, params object[] kryptonParams);

这消除了过载之间的模糊性。

如果你想要你定义的两种方法,那么你可以简单地给它们不同的名称,以避免任何歧义并澄清它们的用法:

public static void CallSuperManforHelpFormatted(string helpMessage, params object[] kryptonParams)
public static void CallSuperManforHelp(string helpMessage ,string sender,string senderZipCode)

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM