我通过值将一个参数/对象传递给函数“RefValTest(object oIn)”但是在函数调用超过对象后传递的值被更改,那不应该发生,对吗?
class MilanTest
{
public int SomeValue { get; set; }
}
class PR
{
public static object RefValTest(object oIn)
{
PropertyInfo tProperty = oIn.GetType().GetProperty("SomeValue");
tProperty.SetValue(oIn, 5, null);
return null;
}
}
主要的某个地方:
MilanTest x = new MilanTest ();
//here is by compiler default x.Somevalue == 0
PR.RefValTest(x);
//here is by compiler default x.Somevalue == 5
对象x.SomeValue的“PR.RefValTest(x)”值调用后如何更改?
BR, 米兰。
答案 0 :(得分:2)
非常简单:传递给方法的是对象的引用。然后,您将更改该对象中的数据。因此,当您再次查看对象后,您可以看到更改。
您不需要使用反射来查看此工作 - 这是您的代码的更简单版本:
class MilanTest
{
public int SomeValue { get; set; }
}
class Test
{
static void RefValTest(MilanTest x)
{
x.SomeValue = 5;
}
static void Main()
{
MilanTest t = new MilanTest();
RefValTest(t);
Console.WriteLine(t.SomeValue); // Prints 5
}
}
有关详细信息,请参阅my article on parameter passing。
答案 1 :(得分:2)
问题在于你混淆了你所传递的内容,并且“按值”传递一个对象永远不会有效。
当您传递引用类型(从System.Object
派生的任何内容)时,您传递的是到该对象的引用 - 而不是对象本身。基本上你传递的是存储对象数据的内存地址。无论您是通过引用还是通过值传递,方法内部发生的是地址跟随到原始对象。无论您传递“地址指针”还是“地址副本”,地址本身都不会改变。
因此,无论您如何传递该类型,您都会发现原始对象就是您正在修改的对象。如果你真的需要这个功能,你的另一种选择是创建一个对象的克隆并传入克隆(或者让你的方法创建克隆本身)。这样就可以修改克隆而不是原始对象。
答案 2 :(得分:0)
您无法更改参考oIn
,但可以更改其属性。
所以在你的方法中,如果你说
oIn = "SomeString";
外面你不会看到这个。
答案 3 :(得分:0)
错误。无论您是直接设置值还是绕过反射,都会发生 。这是传递引用的意思:您正在与同一个对象实例交互,而不是复制。