0

I was scrolling through the MySQL connector code for .NET Core.

I saw the following code:

public async Task DeleteAsync
{
    var cmd = Db.Connection.CreateCommand() as MySqlCommand;
    cmd.CommandText = @"DELETE FROM `BlogPost` WHERE `Id` = @id;";
    BindId(cmd);
    await cmd.ExecuteNonQueryAsync();
}

private void BindId(MySqlCommand cmd)
{
    cmd.Parameters.Add(new MySqlParameter
    {
        ParameterName = "@id",
        DbType = DbType.Int32,
        Value = Id,
    });
}   

Wouldn't this cause the method call

await cmd.ExecuteNonQueryAsync();

to be parameterless?

Full code on https://mysql-net.github.io/MySqlConnector/tutorials/net-core-mvc/

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214

3 Answers3

2

You seem to be confused about how the passing semantics work in C#. You have probably heard that C#, by default, always pass variables by value which is correct. However, C# has two different types of variables: value types and reference types.

If MySqlCommand was a value type (a struct), you would have been correct in your assumption that it would be copied into the BindId method. However, MySqlCommand is a class and therefore a reference type.

When you pass a reference type to a method, C# creates a copy of the reference to the object in memory. So the reference in BindId still references the same MySqlCommand object in memory.

I hope this makes sense. I recommend reading some of the official documentation on the subject:

Passing Parameters

MAV
  • 7,260
  • 4
  • 30
  • 47
  • Yeah, that was my confusion, feeling really dumb right now, and have a lot of code that makes no sense after knowing this... Classes, interfaces, objects and are all reference types and structs and enumerators are value types. – Mario Figueiredo May 18 '19 at 11:58
  • 1
    No reason to feel dumb. It's a subject that is often misunderstood. :) – MAV May 18 '19 at 12:01
  • 1
    I hate to add a "me, too" but this cannot be emphasized enough. You knew enough to determine exactly why the actual behavior was different from what you expected. That enables you ask the question, get the answer, and add it to what you know. That's exactly what everyone keeps doing every day. It's okay to *feel* dumb - just don't ever believe it. – Scott Hannen May 18 '19 at 12:51
1

It is passing a reference to the command (because it is a reference-type, i.e. an object) as the parameter/argument, and that reference is being passed by value, i.e. a separate copy of the reference. But: that's basically just like copying a pointer: any copy of the pointer still points to the same location, and thus a copy of a reference still points to the same object. Any changes to the object will be visible to all consumers, that have a copy of the same reference.

The only relevance of "by value" here is that if the BindId method assigns a new value to cmd, then that assignment to a different object won't be visible to the caller - the caller will still only know about the original command object.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
0

.Net has 2 fundamental types. Reference and value types.

Reference type values itself resides in the heap, but reference of that value which point to the location of the heap itself resides in the stack, when you pass reference value to the method CLR creates the copy of the that reference and pass that copy. But since it is reference, it still points to the original value.

Value types value itself resides in the stack and value types do not have references. When you pass value type to the method CLR creates the copy of that value and pass it. And if you would do some operations with that value original would not be corrupted. From John Skeet's blog

Suppose we have printed pages about countries list and web site which contains the same info as printed pages.

The information would be the same, but the two media types behave in different ways. Printed pages have value semantics and web sites have reference semantics. In other words, printed pages act like value types and web sites act like reference types.The page contains the information directly. When you access a web page, you use a URL to get to it - in our example, the URL is analogous to a reference used to access a reference type object.

Here is the link this is best explanation i have ever seen.

Ref vs value types in .Net Jon Skeet.

So_oP
  • 1,211
  • 15
  • 31