Search code examples
c#return-valuebyref

Most efficient way to mainupulate a object - byref or return value


Since in C# value types are transportet ByValue when used as parameter for a function whereas objects are transported ByRef. So my question is: What is better (faster/more performant/takes less memory)?

To give you a sample:

    public void ChangeObjectByRef(MyObject mo)
    {
        mo.Name = "Test2";
        mo.Values.Add("Value4");
    }

    public MyObject ChangeObjectReturnValue(MyObject mo)
    {
        mo.Name = "Test2";
        mo.Values.Add("Value4");
        return mo;
    }

    public void ChangeMyObject()
    {
        MyObject mo1 = new MyObject()
        {
            ID = 1,
            Name = "Test",
            Values = new List<string>(){
                "Value1", "Value2", "Value3"
            }
        };

        MyObject mo2 = new MyObject()
        {
            ID = 1,
            Name = "Test",
            Values = new List<string>(){
                "Value1", "Value2", "Value3"
            }
        };

        ChangeObjectByRef(mo1);
        mo2 = ChangeObjectReturnValue(mo2);

        Console.WriteLine(mo1.ToString());
        Console.WriteLine(mo2.ToString());

    }
    public class MyObject
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public List<string> Values { get; set; }
        public override string ToString()
        {
            return string.Format("[ID={0}, Name={1}, Values={2}", ID, Name, string.Format("[{0}]", string.Join(", ", Values)));
        }
    }

The result is the same (obvious). But is there a difference between these two methodes?


Solution

  • You're not actually working with value types, see link for details of value types. What you are actually passing is a pointer to that object rather than the object itself. So extending on what @juharr has put in the comments you will lose mo2 as you are overriding it with the pointer of your first object. See code example of what would actually happen

    
     class Program
        {
            static void Main(string[] args)
            {
                Demo demo = new Demo { A = "ABC" };
                Demo demo2;
                OptionOne(demo);
                Console.WriteLine(demo.A); //Outputs World
                demo2 = OptionTwo(demo);
                Console.WriteLine(demo.A); //Outputs Hello
                Console.WriteLine(demo2.A); //Output Hello
                Console.ReadKey();
            }
    
            private static void OptionOne(Demo demo)
            {
                demo.A = "World";
            }
            private static Demo OptionTwo(Demo demo)
            {
                demo.A = "Hello";
                return demo;
            }
        }
        public class Demo
        {
            public string A { get; set; }
        }