【问题标题】:Overloading functions, which have format and params args, with new string argument使用新的字符串参数重载具有格式和参数参数的函数
【发布时间】:2016-10-27 17:32:28
【问题描述】:

我有这样一个函数和它的重载:

  1. SomeMethod(String format, params Object[] prms)
  2. SomeMethod(String str, Exception ex, String format, params Object[] prms)

问题是,当我使用签名的第二个变体时,我的应用程序决定通过第一个变体并使用“str”作为格式。我可以在不更改 params 数组类型的情况下以某种方式避免这种情况吗(在我的情况下我没有机会这样做)?

【问题讨论】:

  • 你到底是怎么称呼它的?我无法重现。
  • 您能说明如何调用第二种方法吗?我试图创建一个原型,当我调用第二种方法时,它只调用第二种方法。
  • @juharr 是否有可能调用具有 4 个参数的方法来调用它的重载,而不是仅使用 2 个参数?我不这么认为......不是在 C# 中
  • @meJustAndrew 当第二个具有params 修饰符并且是object 的数组时。尝试使用SomeMethod("", 1, 2, 3); 调用它
  • 你用的是什么版本的c#?您总是可以通过 SomeMethod(str:"", ...)SomeMethod(format:"", ...) 来强制执行此操作

标签: c# overloading params


【解决方案1】:

似乎如果参数二的类型为Exception,则首选第二个重载,因为转换Exception -> Exception 优于Exception -> Object。 @MatthewWhited 指出,您可以传入命名参数以强制调用一个或另一个重载。

7.5.3.2 更好的函数成员 C# 4 规范

为了确定更好的函数成员,构造了一个精简的参数列表 A,其中仅包含参数表达式本身,按照它们在原始参数列表中出现的顺序。 每个候选函数成员的参数列表按以下方式构造:
• 如果函数成员仅适用于扩展形式,则使用扩展形式。
• 从参数列表中删除没有对应参数的可选参数
• 参数被重新排序,以便它们出现在参数列表中与相应参数相同的位置。
给定一个带有一组参数表达式 { E1, E2, ..., EN } 的参数列表 A 和两个适用的函数成员 MP 和 MQ,参数类型为 { P1, P2, ..., PN } 和 { Q1, Q2, ..., QN }, MP 被定义为比 MQ 更好的函数成员 if
• 对于每个参数,从 EX 到 QX 的隐式转换并不优于从 EX 到 PX 的隐式转换,并且
• 对于至少一个论点,从EX 到PX 的转换优于从EX 到QX 的转换。

以下代码调用方法#1、#1、#1、#2、#2

public class test_params
{
    public void SomeMethod(String format, params Object[] prms) { Console.Write("#1: ");  Console.WriteLine(format, prms); }
    public void SomeMethod(String str, Exception ex, String format, params Object[] prms) { Console.Write("#2 "); Console.WriteLine("str={0} Excep={1}", str, ex.Message); Console.WriteLine(format, prms); }
    public void Test()
    {
        SomeMethod("", 1, 2, 3);                                            // #1:
        SomeMethod("{0} {1}", 1, 2);                                        // #1: 1 2
        SomeMethod("{0} {1}", 1, "p2", 3, 4);                               // #1: 1 p2
        SomeMethod("{0} {1}", new Exception("Test excep"), "p2");           // #2 str={0} {1} Excep=Test excep // p2
        SomeMethod("Str1", new Exception("Test excep"), "{0} {1}", 1, 2);   // #2 str=Str1 Excep=Test excep // 1 2
    }
}

【讨论】:

  • 请注意,如果您调用 SomeMethod("", new Exception()),它应该解析为 #1 而不是 #2。
  • 是的,没有第三个参数它不能匹配第二个重载。我对为什么 OP 看到不同的行为感兴趣。基本的函数匹配规则与 Visual Studio .Net 2003 类似。最好了解匹配意外重载的极端情况的详细信息。
  • 也许他正在使用单声道编译器或其他东西。他们确实知道不符合 c# 规范的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多