不同签名的函数,但编译器调用了错误的函数

3
我有两个功能:
partial class Database
{
    public void Insert(string table, params string[] values)
    {
        string query = "INSERT INTO [{0}] VALUES ('{1}')";
        ExecuteNonQuery(string.Format(query, table, string.Join("','", values)));
    }

    public string Insert(string table, string returnedColumn, params string[] values)
    {
        string query = "INSERT INTO [{0}] OUTPUT INSERTED.{1} VALUES ('{2}')";
        return ExecuteScalar(string.Format(query, table, returnedColumn, string.Join("','", values))).ToString();
    }
}

这两个函数都在数据库的一个表上执行INSERT。区别在于第一个只将数据插入到数据库中,而第二个还使用SQL中的OUTPUT关键字返回插入行中某一列的值。

问题在于当我尝试调用第一个函数时,编译器会调用第二个函数。例如,如果我的代码是这样的:

Database DB = new Database();
DB.Insert("tableName", "some data");

实际上,Visual Studio将其视为我调用了第二个函数:

enter image description here

问题是什么以及如何解决?谢谢。


1
问题在于你调用了Insert(string, string),因为params是可选的。你的编译器基本上认为它应该选择第二个,因为它更匹配。 - Blackunknown
1
我不确定你是否阅读了与我相同的C#规范,但那是正确的重载调用。为什么不呢? - Luaan
2
我认为你应该给这些方法不同的名称,因为它们正在执行不同的操作。 - Matthew Watson
2
我强烈建议你听从@MatthewWatson的意见。正如我在答案中所补充的那样。当然,最终选择由你决定 :) - Blackunknown
1
如果你不加以处理,某人意外调用错误的方法的概率非常高。 - Matthew Watson
显示剩余3条评论
3个回答

5
您可以将第二个参数用数组包装起来,这将强制选择您想要的重载:
DB.Insert("tableName", new[] { "some data" });

4
问题在于您调用了Insert(string, string)方法,因为params参数是可选的。您的编译器基本上认为它应该选择第二种方法,因为它更匹配。
我的第一反应是给这两个方法取不同的名字。既然叫做Insert的方法应该做它所说的事情:插入东西。如果它返回一些内容,我想在调用函数之前知道那是什么。当然,我可以读取第二个参数并知道它返回什么。

3

使用命名参数进行调用

        Database d = new Database();

        //ExecuteScalar
        d.Insert(table: "demoTabele", returnedColumn: "returnedColumn",values: new string[]{"rest arguments1", "rest arguments2"});

        //ExecuteNonQuery
        d.Insert(table: "demoTabele", values: new string[] { "rest arguments1", "rest arguments2" });

这是一个很棒的答案。我真的不知道选择它还是@Lee的答案。两个都是非常好的解决方案。 - Michael Haddad
这是最好的和最相关的答案,我不应该重命名我的函数,只是因为它重载了以前的函数。 - Emanuel Vintilă

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接