0

我有一组从一个 BaseObject 继承的对象,这些对象具有一些全局原始属性(索引等)。现在,我有两个对象,其中一个(目标对象)仅具有基本属性的值,另一个(源,它是一组对象之一)具有所有其他属性的值(从第三个派对应用程序),但基本的。

我正在尝试将所有源对象的属性复制到目标对象,但保留目标的基本属性值。换句话说——我试图在不删除任何内容的情况下使两个对象的属性值相等…… 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”关键字吗?

4

1 回答 1

3

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

例子:

// 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
--------------------------------------------+-------------------+----------------------

如果你不使用可变结构,那么结构类型的变量只能通过重新赋值来改变,然后下面的经验法则对值类型和引用类型都很有用:

当且仅当您的方法将(包括复合分配 like )分配给相关参数时,您才需要ref(or out) 关键字。+=

另请参阅C# 中引用类型变量的“ref”有什么用?.

于 2013-05-02T10:45:44.140 回答