获取不会更改其父对象值的对象的副本

时间:2013-03-21 15:49:52

标签: c# linq

我有一个对象类TimeDuration。当我尝试更改从数组Span获取的对象的值时,数组内的值也会更改。如何获取不会更改其父对象值的对象的副本?我需要将此副本传递给另一个函数,我必须对此对象进行更改

 public void test()
        {
            List<TimeDuration> Span = new List<TimeDuration>();
            TimeDuration ob = new TimeDuration();
            ob.FromTime = DateTime.Now;
            ob.ToTime = DateTime.Now.AddDays(1);
            Span.Add(ob);

           //Trying to assign value here!
           TimeDuration ob2= Span[1];
           ob2.FromTime = DateTime.Now.AddDays(3);

        }

public class TimeDuration
    {
        public DateTime FromTime { get; set; }
        public DateTime ToTime { get; set; }
    }

5 个答案:

答案 0 :(得分:6)

首先,您应该理解当前代码的行为方式。有关详细信息,请参阅my article on reference types and value types

  

如何获取不会更改其父对象值的对象的副本?

两个简单的选择:

  • 创建某种克隆方法,创建现有对象的副本。您需要明确地执行此操作 - 尽管在某些情况下您可以使用object.MemberwiseClone作为快捷方式。在许多情况下,它很简单,虽然继承使其更难。
  • 让您的TimeDuration类不可变,例如使用WithToTime返回的方法 一个版本:

    public TimeDuration WithFromTime(DateTime newFromTime)
    {
        return new TimeDuration(newFromTime, ToTime);
    }
    

    您将属性设置为只读,并提供一个构造函数来获取两个值(也可以验证它们)。你甚至可以考虑使它成为一个结构。

答案 1 :(得分:1)

考虑将类转换为结构,当然也使它成为不可变的:

public struct TimeDuration
{
    public DateTime FromTime { get; private set; }
    public DateTime ToTime { get; private set; }

    public TimeDuration(DateTime fromTime, DateTime toTime) : this()
    {
        FromTime = fromTime;
        ToTime = toTime;
    }

    public TimeDuration SetFromTime(DateTime fromTime)
    {
        var copy = this;
        copy.FromTime = fromTime;
        return copy;
    }

    public TimeDuration SetToTime(DateTime toTime)
    {
        var copy = this;
        copy.ToTime = toTime;
        return copy;
    }
}

答案 2 :(得分:1)

TimeDuration成为struct而非class:值类型按值传递,因此您将获得一种“复制”行为。

答案 3 :(得分:0)

类是引用类型。数组内部的值是指向TimeDuration对象的内存位置的指针,而不是它的新实例。因此,当您更改值时,它也会影响数组。

您必须创建一个TimeDuration的新对象并传递它。

答案 4 :(得分:0)

如果您始终以这种方式使用TimeDuration,则可以考虑将其从class更改为struct。要复制class,您应该实施ICloneable并调用Clone方法。