Michael Haddad
Michael Haddad

Reputation: 4435

Functions with different signature, but the compiler calls the wrong one

I have two functions:

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();
    }
}

Both of them are executing an INSERT on a table in the database. The difference is that while the first one only inserts the data into the database, the second also returns a value from one of the columns in the inserted row, using the OUTPUT keyword in SQL.

The problem is that when I am trying to call the first function, the compiler calls the second one. So, for example, if I have this code:

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

Visual studio actually treats it as if I called the second function: enter image description here

What is the problem and how can I solve it? Thanks.

Upvotes: 3

Views: 2598

Answers (3)

Moumit
Moumit

Reputation: 9530

call it by using named parameter

        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" });

Upvotes: 3

Blackunknown
Blackunknown

Reputation: 305

The problem is that you are calling Insert(string, string), because params is optional. Your compiler basically thinks it should pick the second one because it matches more closely.

My first instinct would be to name the methods differently. Seeing as a method called Insert should do what it says: insert stuff. If it returns something I would like to know what that resembles before I call the function. Of course I can read the 2nd parameter and know what it returns.

Upvotes: 4

Lee
Lee

Reputation: 144136

You can wrap your second argument in an array which will force the overload you want to be chosen:

DB.Insert("tableName", new[] { "some data" });

Upvotes: 5

Related Questions