C#:执行该函数后,为什么不修改该对象?

时间:2011-09-19 15:11:55

标签: c#

我一直认为在C#中总是作为引用传递的对象,如果函数修改了它,那么父方法应该具有该对象的修改版本。但是,阅读导致错误的旧开发人员留下的这段代码让我觉得情况并非如此。代码如下:

Item item = new Item();
PopulateItem(sodItem, id, item);

功能代码如下:

private void PopulateItem(eSodTypes.Item sodItem, int id, Item item)
        {

                if (sodItem != null)
                {
                    item = (Item)sodItem;
                    item.Delivery = (Delivery)sodItem.Delivery;
                    if (sodItem.Delivery != null)
                    {
                        item.Delivery.DeliveryContact = (CustomerContact)sodItem.Delivery.DeliveryContact;
                        item.Delivery.DeliveryAddress = (Address)sodItem.Delivery.DeliveryAddress;
                        item.Delivery.ShippingInstructions = (ShippingInstructions)sodItem.Delivery.ShippingInstructions;
                    }
                    item.Installation = (Installation)sodItem.Installation;
                    item.Training = (Training)sodItem.Training;
                    item.Service = (Service)sodItem.Service;
                    item.Service.Address = (Address)sodItem.Service.Address;
                    if (sodItem.Service.Address != null)
                        item.Service.Address.Contact = (CustomerContact)sodItem.Service.Address.Contact;
                    item.Service.Customer = (Customer)sodItem.Service.Customer;
                    if (sodItem.ItemLines != null)
                        item.ItemLines = sodItem.ItemLines.Items.ToList().ConvertAll(new Converter<eSodTypes.ItemLine, ItemLine>(ItemLine.ItemLineTypeToItemLineTypeModel));
                }
        }

如果我对其工作的项目使用“ref”,但我认为这仅适用于“int”或“double”等值类型。

3 个答案:

答案 0 :(得分:17)

我假设您的意思是您希望在从方法返回时修改'item'。问题出在这里:

item = (Item)sodItem;

您正在修改变量项以指向参数sodItem,因此它不再指向传入的相同项。原始引用“item”从未被修改过。当您将item参数更改为'ref'时,这会导致作为参数传递的变量的原始引用发生更改。

请注意,此当前代码实际上是修改原始sodItem(将自己的值复制回自身),这可能不是您的意图。

答案 1 :(得分:13)

我有一张纸上写着地址:123芝麻街。我递给你一张那张纸的复印件。

你前往123芝麻街,找到一个蓝色的房子。你把房子涂成绿色。

然后在您的复印件上划掉123芝麻街,并将其更换为宾夕法尼亚大道1600号。

我的纸上的地址不会改变。我去芝麻街123号,果然,房子现在是绿色的。

你知道吗?当我复印时, house 被“通过引用传递”。那张纸不是房子;它是对房子的参考。该引用的副本仍然是对房屋的引用。更改一个引用不会更改任何其他引用;更改引用的事物的颜色会改变所有引用的颜色。

相反,假设我与你分享我的一张纸,而不是复制。现在如果你划掉123芝麻街并用1600宾夕法尼亚大道取代它,我看到了变化,因为我们分享相同的参考。您可以使用“ref”关键字与方法共享变量。

有意义吗?

答案 2 :(得分:4)

您必须使用ref关键字才能使其生效。区别是微妙的...当你传递一个对象时,指针通过值传递...即它被复制。所以现在你有两个指针指向同一个东西。然后,当您将新对象分配给参数指针时,不会影响原始指针..它仍然指向原始对象。

使用ref时,指针实际上是传递的,所以如果重新分配它,那么原始指针也会被重新分配。

此处有更多信息... http://msdn.microsoft.com/en-us/library/14akc2c7.aspx

为了让你的工作,你要么......

a)需要使用ref关键字或 b)做这个项目=(项目)sodItem;在将其传递给方法之前