3

Hi I am new to C# development environment. Can anyone help me.

Modify the Coffee class implementation so that a list stored in the Coffee is not affect by modifications of either the original or restored list.

using System;
using System.Collections.Generic

public class Coffee 
{
    private List<int> info;
    public Coffee(List<int> info)
    {
      this.info = info;
    }
    public List <int> Restore()
    {
      return this.info;
    }
}

I am not looking an answer(spoon feeding) here but direction, on what should I be reading on. I am a PHP developer. Thank you in advance

Sir Rufo
  • 18,395
  • 2
  • 39
  • 73
  • 2
    Look into copying - deep and shallow copy (with ints all youll need is shallow but still) – Gilad Green Jul 20 '17 at 06:22
  • Notice that is is not a good SO question as, even if you looked around a lot, it is still a "do my homework"/"give me some reference" question... Avoid these kind of questions in the future. They usually are closed and downvoted ;) – Gilad Green Jul 20 '17 at 06:24
  • You´re worries are unneccessary, as `int` is a value-type which is copied "deeply" anyway. The same applies to all other value-types. However if you have a list of some instances of a class (a reference-type), you´ll need adeep copy. In this case there are thousands of duplicates for this question, just ggole for "deep clone c#" – MakePeaceGreatAgain Jul 20 '17 at 06:25
  • @HimBromBeere: Note that a value type *containing* a reference to a mutable type would still need to be deep-cloned. – Jon Skeet Jul 20 '17 at 06:26
  • @HimBromBeere - half true. By returning a reference to that list items could be added to it – Gilad Green Jul 20 '17 at 06:26
  • Note: The OP is primarily looking for a **direction** how to solve and not the solution itself. – Sir Rufo Jul 20 '17 at 06:53
  • By modification to the list do you mean modification to the elements *within* the list (which isn´t even possible on `list`), or just modifications to the list itself (adding, removing elements)? – MakePeaceGreatAgain Jul 20 '17 at 07:08

4 Answers4

4

You can use LINQ to make a copy of the list by adding .ToList() on the way in (so you have your own copy that is not affected by changes to the original) and on the way out (so the caller gets their own copy, so their changes do not affect you)

using System;
using System.Collections.Generic

public class Coffee 
{
    private List<int> info;
    public Coffee(List<int> info)
    {
      this.info = info.ToList();
    }
    public List <int> Restore()
    {
      return this.info.ToList();
    }
}
Colin Mackay
  • 18,736
  • 7
  • 61
  • 88
  • 1
    This only works because we have a list of int, however it´ll also work without even calling `ToList` as mentioned by Gilad Green – MakePeaceGreatAgain Jul 20 '17 at 06:25
  • I am unable to fully parse your sentence. Why is the fact it is a List of any importance at all? – Colin Mackay Jul 20 '17 at 06:26
  • If it wehere a `List – MakePeaceGreatAgain Jul 20 '17 at 06:27
  • 3
    The OP said they didn't want modification to the list, not that they didn't want modification to the objects in the list. A shallow copy is sufficient for what the OP asked for. And in any event with immutable objects (such as int) deep copying is not required as it is immutable and cannot be changed. – Colin Mackay Jul 20 '17 at 06:28
  • 3
    The question is about modifying the list, not the objects that it contains, so I would consider this a valid answer. The talk of needing a deep clone seems to be reading too much into the question. – Rob Hill Jul 20 '17 at 06:32
1

Create new instance of your List

Using System;
Using System.Collections.Generic

public class Coffee 
{
    private List<int> info;
    public Coffee(List<int> info)
    {
       this.info = new List<int>(info);
    }
    public List <int> Restore()
    {
       return new List<int>(this.info);
    }
}
Dmitry
  • 512
  • 7
  • 15
  • 2
    Why this answer is downloaded? It fit OP requirements, changes of list passed in constructor and changes of the list returned by `Restore` method will not affect on private `info` list. Requirements was: _so that a list stored in the Coffee is not affect by modifications of either the original or restored list_ – Fabio Jul 20 '17 at 06:32
  • Looks like we will not get an answer to question about downvoting. – Dmitry Jul 20 '17 at 06:56
0

If you're using a modern .NET version, one approach is to return a ReadOnlyCollection<T> object--this is a wrapper around your collection that will throw exceptions if you try to modify it. List<T>.AsReadOnly() creates this wrapper. But it's not statically typesafe--it won't prevent you from writing bad code. It definitely won't prevent someone from modifying the elements themselves: roList[3].name = "foo";

Another approach is to copy the list. This is safe, works in older .NET versions, but has overhead. When elements are inserted, the new list will be modified. Since it's not a deep copy, elements can be be changed just as in the previous example.

A third possibility is to cast the object to IEnumerable<T> before returning it, which does not have a list accessor API at all. You can still loop over the elements with foreach. This will actually prevent you from writing the illegal code, unless the object is cast back to List<T>. It will make the code that uses the list a little slower and less convenient to write, as the API is more limited than List<T>.

None of these approaches use a deep copy, which would be the only really safe way to prevent object modification. Since deep copy isn't possible for many types of objects, it's not a viable solution.

piojo
  • 6,351
  • 1
  • 26
  • 36
-2

You may store it as IReadOnlyList<int>

public class Coffee
{
    private IReadOnlyList<int> info;
    public Coffee(List<int> info)
    {
        this.info = info; // You can view original collection in readonly mode
    }
    public List<int> Restore()
    {
        return info.ToList(); // Makes a copy of original list
    }
}

UPDATE: sorry for missing condition. In case if you want to store independent copy of list, you may use Colin Mackay's solution.

PS: no need to be so aggressive and immediately downvote each answer. This code example also may be useful to understand C# for newcomer

opewix
  • 4,993
  • 1
  • 20
  • 42
  • 1
    The originator of the list can still modify the list after passing it to the coffee class and that was one of the conditions. – Colin Mackay Jul 20 '17 at 06:25