-1

I have an object class TimeDuration. When I tried to change the value of object taken from the array Span, the value inside the array also changes. How can I get copy of an object that won't change its parent object value? I need to pass this copy to another function where I have to make changes to this object

 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; }
    }
4

5 回答 5

6

Firstly, you should understand why the current code behaves as it does. See my article on reference types and value types for more details.

How can I get copy of an object that won't change its parent object value?

Two simple options:

  • Create some sort of cloning method which creates a copy of the existing object. You need to do this explicitly - although you could use object.MemberwiseClone as a shortcut in some cases. In many cases it's pretty simple, although inheritance makes it harder.
  • Make your TimeDuration class immutable, e.g. with methods of WithToTime returning a new version:

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

    You'd make your properties read-only, and provide a constructor taking both values (which can also validate them). You might even consider making it a struct at this point.

于 2013-03-21T15:52:49.947 回答
1

Consider turning the class into a struct, and of course also make it immutable:

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;
    }
}
于 2013-03-21T15:53:59.563 回答
1

Make your TimeDuration a struct instead of a class: value types are passed by value, so you will get a kind of "copy" behaviour.

于 2013-03-21T15:54:40.427 回答
0

Classes are reference types. The value inside the array is a pointer to the memory location of your TimeDuration object and not a new instance of it. Therefore when you change the value it affects the array also.

You will have to create a new object of TimeDuration and pass that about.

于 2013-03-21T15:52:39.273 回答
0

If you're always using TimeDuration this way, you may want to consider changing it from a class to a struct. To duplicate a class, you should implement ICloneable and call the Clone method.

于 2013-03-21T15:53:23.647 回答