我对以下代码有疑问:
static void Main(string[] args)
{
var msg = new Message()
{
Description = new Description() { Key = 1, Value = "Foo"},
ID = 1,
Name = "MyMessage"
};
changeDescription(msg.Description);
}
static void changeDescription(Description descrToChange)
{
descrToChange = new Description() { Key = 2, Value = "Foobar" };
}
为什么我的msg在方法调用后有描述(Key = 1,Value =“Foo”)?
类:
class Message
{
public Description Description { get; set; }
public int ID { get; set; }
public string Name { get; set; }
}
class Description
{
public int Key { get; set; }
public string Value { get; set; }
}
提前谢谢
编辑:如果我建议您使用'ref'关键字,我会收到此错误:
Error CS0206 A property or indexer may not be passed as an out or ref parameter
答案 0 :(得分:6)
在您的方法中,您创建了一个全新的Description
实例。对此实例的引用存储在本地变量descrToChange
中。
descrToChange
作为参数,是引用变量msg.Description
的副本。 descrToChange
中的原始引用会在您的方法中被覆盖,msg.Description
内的引用仍然相同。
*解决方案#1:使用已创建的实例*
一种解决方案可能是修改引用变量已指向的实例的成员。您不在方法中创建新实例,只需使用已存在的实例:
static void changeDescription(Description descrToChange)
{
descrToChange.Key = 2;
descrToChange.Value = "Foobar";
}
*解决方案#2:使用父级修改其子级
另一种解决方案可能是使用Message
作为参数:
static void changeDescription(Message msg)
{
msg.Description = new Description() { Key = 2, Value = "Foobar" };
}
并将其称为:
changeDescription(msg);
*解决方案#3:使用ref
修改参考(在变量内)*
如果msg.Description
是一个字段而不是一个属性,并且您想通过该方法在msg.Description
内修改该引用,请使用ref
。请注意:明智地使用此关键字:
static void changeDescription(ref Description descrToChange)
{
descrToChange = new Description() { Key = 2, Value = "Foobar" };
}
并使用以下方法调用此方法:
changeDescription(ref msg.Description);
这只有在您的财产属于某个字段时才有效,我不建议:
class Message
{
public Description Description;
public int ID { get; set; }
public string Name { get; set; }
}
答案 1 :(得分:3)
为什么我的消息后面有描述(Key = 1,Value =" Foo") 方法调用?
因为您没有使用ref
关键字。
static void changeDescription(ref Description descrToChange)
{
descrToChange = new Description() { Key = 2, Value = "Foobar" };
}
此外,您还必须将方法调用更改为以下方法:
changeDescription(ref msg.Description);
ref关键字导致参数通过引用传递,而不是通过引用传递 值。通过引用传递的效果是任何改变 被调用方法中的参数反映在调用方法中。对于 例如,如果调用者传递局部变量表达式或数组 元素访问表达式,被调用的方法替换该对象 ref参数引用的,然后是调用者的局部变量或 数组元素现在引用新对象。
有关ref
关键字的详细信息,请查看here。
现在让我们了解一下:
descrToChange = new Description() { Key = 2, Value = "Foobar" };
在上面的代码行中,我们创建了一个新的Description
对象,然后将其分配给descrToChange
。但是,此变量descrToChange
作为参数传递给方法,并且可以保存类型为Description
的对象的引用。我们可以将类型为Description
的对象传递给方法,然后更改它的数据,但我们无法更改对该对象的引用。如果这是你的意图,那么你应该通过引用传递参数。
答案 2 :(得分:0)
你覆盖了参考文献。您可以改为更改现有对象。
static void changeDescription(Description descrToChange)
{
descrToChange.Key = 2;
descrToChange.Value = "Foobar";
}