好,
也许这是c#的设计,或者我可能会采用错误的方式。
请查看下面的代码。我把它复制并粘贴到控制台应用程序中并运行它以查看我在说什么。
using System;
namespace ConsoleTest
{
class Program
{
static void Main()
{
var o1 = new oObject
{
Name = "Before Method"
};
var o1b = new oObjectBad
{
Name = "Before Method"
};
Console.WriteLine("Object Bad 1 Before: " + o1b.Name);
oObjectBad o2b = GetNewObjectBad(o1b);
Console.WriteLine("Object Bad 1 After: " + o1b.Name);
Console.WriteLine("Object Bad 2 After: " + o2b.Name);
Console.WriteLine(string.Empty);
Console.WriteLine("Object 1 Before: " + o1.Name);
oObject o2 = GetNewObject(o1);
Console.WriteLine("Object 1 After: " + o1.Name);
Console.WriteLine("Object 2 After: " + o2.Name);
Console.ReadLine();
}
public static oObject GetNewObject(oObject o)
{
oObject newObject = new oObject(o);
newObject.Name = "Changed in Method";
return newObject;
}
public static oObjectBad GetNewObjectBad(oObjectBad o)
{
o.Name = "Changed in Method";
return o;
}
}
class oObject
{
public oObject()
{
}
public oObject(oObject o)
{
Name = o.Name;
}
public string Name { get; set; }
}
class oObjectBad
{
public string Name { get; set; }
}
}
现在,这是我不明白的地方。
当我将一个对象传递给该方法时,并更新对象属性“Name”。然后它更新方法之外的原始对象。
解决这个问题的方法是创建另一个对象(如代码所示)来复制对象,然后更新克隆,然后返回克隆。
所以问题是: 有没有更简单的方法来传递一个对象并更新该对象的属性,所以我可以有这样的东西,而不更新原始对象。
using System;
namespace ConsoleTest
{
class Program
{
static void Main()
{
var o1 = new oObject
{
Name = "Before Method"
};
Console.WriteLine("Object 1 Before: " + o1.Name);
oObject o2 = GetNewObjectBad(o1);
Console.WriteLine("Object 1 After: " + o1.Name);
Console.WriteLine("Object 2 (New Object) After: " + o2.Name);
Console.ReadLine();
}
public static oObject GetNewObjectBad(oObject o)
{
o.Name = "Changed in Method";
return o;
}
}
class oObject
{
public string Name { get; set; }
}
}
如果这令人困惑,请告诉我,我会看看我是否可以更好地解释。
编辑: 我这样做的原因是我需要克隆数据库中的对象,克隆的对象需要更改几个属性。然后我将使用原始对象的ID和新对象进行其他数据处理。
谢谢!
答案 0 :(得分:2)
我会花一些时间研究按引用传递而不是按值传递,然后查看为什么需要在本地上下文中更改名称而不是原始名称。我怀疑你可能有一些设计缺陷。我会重新审视这个问题,看看你是否可以用不同的方法开发解决方案。
答案 1 :(得分:1)
为什么要更改方法中的对象而不是在调用方法中反映这些数据?您可以做的一件事是实现代码来跟踪更改,并为类提供一个方法,使原始数据返回原始对象。
正如其他人所说,这是一种价值类型与参考类型的问题。如果您确实希望不更改对象,可以将类型更改为结构。我不是说这就是答案,我不知道你的班级结构,就此事做出明智的意见。
答案 2 :(得分:0)
在.NET中,所有对象都是引用类型,除非它们来自ValueType。通常,您不希望直接修改对象的实例变量。如果将实例变量设为私有,则可以进行更多控制,然后添加方法来操作私有数据。
http://msdn.microsoft.com/en-us/library/s1ax56ch.aspx ValueType的死者名单。