在方法内部/外部更新对象

时间:2009-05-13 19:06:11

标签: c# object

好,

也许这是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和新对象进行其他数据处理。

谢谢!

3 个答案:

答案 0 :(得分:2)

我会花一些时间研究按引用传递而不是按值传递,然后查看为什么需要在本地上下文中更改名称而不是原始名称。我怀疑你可能有一些设计缺陷。我会重新审视这个问题,看看你是否可以用不同的方法开发解决方案。

答案 1 :(得分:1)

为什么要更改方法中的对象而不是在调用方法中反映这些数据?您可以做的一件事是实现代码来跟踪更改,并为类提供一个方法,使原始数据返回原始对象。

正如其他人所说,这是一种价值类型与参考类型的问题。如果您确实希望不更改对象,可以将类型更改为结构。我不是说这就是答案,我不知道你的班级结构,就此事做出明智的意见。

答案 2 :(得分:0)

在.NET中,所有对象都是引用类型,除非它们来自ValueType。通常,您不希望直接修改对象的实例变量。如果将实例变量设为私有,则可以进行更多控制,然后添加方法来操作私有数据。

http://msdn.microsoft.com/en-us/library/s1ax56ch.aspx ValueType的死者名单。