传入c#的参数不能正常工作?内部功能使用反射

时间:2010-03-03 11:42:19

标签: c# reflection arguments

我通过值将一个参数/对象传递给函数“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, 米兰。

4 个答案:

答案 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)

错误。无论您是直接设置值还是绕过反射,都会发生 。这是传递引用的意思:您正在与同一个对象实例交互,而不是复制。