更新对象的最有效方法 - byref 或 return 值
Most efficient way to mainupulate a object - byref or return value
因为在 C# 中,当用作函数的参数时,值类型是按值传输,而对象是按引用传输。所以我的问题是:什么更好(faster/more performant/takes 更少的内存)?
给大家打个比方:
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)));
}
}
结果是一样的(很明显)。但是这两种方法有区别吗?
您实际上并没有使用值类型,请参阅 link 了解值类型的详细信息。您实际传递的是指向该对象的指针,而不是对象本身。因此,扩展@juharr 在评论中提出的内容,您将失去 mo2,因为您正在用第一个对象的指针覆盖它。查看实际发生的代码示例
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; }
}
因为在 C# 中,当用作函数的参数时,值类型是按值传输,而对象是按引用传输。所以我的问题是:什么更好(faster/more performant/takes 更少的内存)?
给大家打个比方:
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)));
}
}
结果是一样的(很明显)。但是这两种方法有区别吗?
您实际上并没有使用值类型,请参阅 link 了解值类型的详细信息。您实际传递的是指向该对象的指针,而不是对象本身。因此,扩展@juharr 在评论中提出的内容,您将失去 mo2,因为您正在用第一个对象的指针覆盖它。查看实际发生的代码示例
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; }
}