我正在浏览.NET Core的MySQL连接器代码。
我看到了以下代码:
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,
});
}
这不会导致方法调用
await cmd.ExecuteNonQueryAsync();
成为无参数?
完整代码已开启 https://mysql-net.github.io/MySqlConnector/tutorials/net-core-mvc/
答案 0 :(得分:2)
您似乎对C#中传递的语义如何工作感到困惑。您可能已经听说,C#默认情况下始终按正确的值传递变量。但是,C#具有两种不同类型的变量:value types和reference types。
如果MySqlCommand
是一个值类型(结构),则假定将其复制到BindId
方法中是正确的。但是,MySqlCommand
是类,因此是引用类型。
当您将引用类型传递给方法时,C#为内存中的对象创建引用的副本。因此,BindId
中的引用仍然引用内存中的同一MySqlCommand
对象。
我希望这是有道理的。我建议阅读有关该主题的一些官方文档:
答案 1 :(得分:1)
它将 reference 传递给命令(因为它是 reference-type ,即对象)作为参数/参数,并且正在传递该引用按值,即参考的单独副本。但是:基本上就像复制指针一样:指针的任何副本仍指向同一位置,因此引用副本仍指向同一对象。该对象的任何更改都将对所有具有相同引用副本的使用者可见。
此处“按值”的唯一相关之处在于,如果BindId
方法将新值分配给cmd
,则分配给另一个对象对呼叫者不可见-呼叫者仍然只知道原始命令对象。
答案 2 :(得分:0)
.Net具有2种基本类型。引用和值类型。
引用类型值本身驻留在堆中,但是当您将引用值传递给方法CLR创建副本时,指向堆自身位置的该值的引用驻留在堆栈中引用并传递该副本。但是,由于它是参考,因此仍指向原始值。
值类型值本身驻留在堆栈中,并且值类型没有引用。当您将值类型传递给方法时,CLR将创建该值的副本并将其传递。而且,如果您要使用该值进行某些操作,原始文件也不会损坏。摘自John Skeet的博客
假设我们已打印了有关国家列表和网站的页面,其中包含与已打印页面相同的信息。
信息将相同,但是两种媒体类型的行为方式不同。打印的页面具有值语义,网站具有参考语义。换句话说,打印页面的行为类似于值类型,而网站的行为类似于引用类型。页面直接包含信息。当您访问网页时,您使用URL进行访问-在我们的示例中,该URL类似于用于访问引用类型对象的引用。
这是我所见过的最好的解释链接。