某些更新将从方法中丢弃

时间:2013-05-02 10:42:34

标签: c# pass-by-reference pass-by-value

我有一组对象继承自一个BaseObject,它有一些全局原始属性(索引等)。现在,我有两个对象,其中一个(目标一个)只有基本属性的值,另一个(源,它是一组对象之一)具有所有其他属性的值(从第3个中检索)派对app),但是基础的。

我正在尝试将所有源对象的属性复制到目标属性,但保留目标的基本属性值。换句话说 - 我试图在不删除任何内容的情况下等于两个对象的属性值... target = source;只会删除目标的基本索引...... 所以,我创建了一个方法,将两个对象(转换为BaseObject)作为参数,并将目标的索引值复制到副本的源,如下所示:

Public void Copy(BaseObject source, BaseObject target)
{
    //Copy all primitive indexes here...
    source.index = target.index;
    source.reference = target.reference;
    etc…

    //Copy the updated object to the target one...    
    target = source;
}

在方法内部的调试模式下似乎没问题,但是 - 当我的代码退出方法时,我很惊讶地看到虽然源对象已经使用继承和非继承属性正确更新,但目标是价值保持不变。 所以,我必须在方法之外再次将(更新的)源复制到目标中,如下所示:

InheritedObject sourceObj = CreateObjectWithPrimitiveIndexes();
InheritedObject targetObj = GetObjectWithNoIndexesFrom3rdParty();

targetObj.Copy(source: sourceObj, target: targetObj);

//The targetObject is not updated, so I have to re-copy it outside the Copy() method
targetObj = sourceObj;

有人可以解释为什么sourceObj被更新,因为它被ref发送到copy()方法,但是目标obj的行为就像它是由val发送的,并且它的所有更新都在方法之外被忽略了......? ?

我可以使用'ref','out'关键词,方法签名等吗?

1 个答案:

答案 0 :(得分:3)

如果分配给方法的参数,则该分配对调用者可见,该参数必须具有ref(或out)修饰符。请参阅ref (C# Reference)

示例:

// doesn't do anything!
void Copy(BaseObject target)
{
    ...
    target = Something;
}

// with ref, assignment is to the *same* variable as the caller gave
void Copy(ref BaseObject target)
{
    ...
    target = Something;
}

<强>此外:

正如我提供的链接说明:

  

不要混淆通过引用传递的概念   与参考类型的概念

这两个概念是“正交的”,如下表所示:

                                            |                   |
                                            | ByVal (neither    |  ByRef (ref or
                                            | ref nor out):     |  out keyword):
                                            |                   |
--------------------------------------------+-------------------+----------------------
value type (struct, enum)                   | entire object     |  no copy, argument
                                            | is COPIED         |  must be a variable,
                                            |                   |  same variable used
--------------------------------------------+-------------------+----------------------
reference type (class, interface, delegate) | reference COPIED; |  no copy, argument
                                            | NEW reference to  |  must be a variable,
                                            | same object       |  same variable used
--------------------------------------------+-------------------+----------------------

如果你不使用 mutable structs ,那么struct类型的变量只能通过re-assignemnt改变,然后以下经验法则对于值类型和引用都是有用的类型:

  

当且仅当您的方法指定时,您需要ref(或out)关键字   (包括像+=这样的复合赋值)到相关参数。

另见What is the use of “ref” for reference-type variables in C#?