0

The actual content of this method isn't important, as the question is specific to the language itself I guess. So here it goes.

Here is my method snippet:

private CellValidation.CellValidationResult Validate<B, I>(CellValidation cellToValidate, IList<B> baseListToValidateAgainst, IList<I> importListToValidateAgainst, string invalidMessage, DDSFieldEnum fieldEnum) where I : Entities.DDS.DDSEntityFieldBase where B : Entities.DDS.

    //Remove all dashes and /'s for a more realistic mapping check. We don't want the mapping to fail just because the imports - may be different. Also, create local variables of the list as don't want to modify the actual db. 
    cellToValidate.Value = cellToValidate.Value.Replace("-", " ").Trim().ToLower();

   // IList<B> baseList;
    var baseList = baseListToValidateAgainst;
    baseList.Select(x => { x.Value = x.Value.Replace("-", " ").Trim().ToLower(); return x; }).
...

So I clearly set local baseList variable to equal the parameter passed in, then I modify the baseList variable.

However, this seems to modify the parameter baseListToValidateAgainst and not only the local variable baseList. Why is that?

2
  • 1
    var baseList = baseListToValidate copies reference to the same collection, it does not copy the collection itself. Commented Oct 26, 2017 at 15:39
  • 1
    @Pankaj example does not create a shallow copy, nor does it create a deep copy. It only copies a reference. Commented Oct 26, 2017 at 15:40

3 Answers 3

1

As mentioned in the comments to your question, you are not making a copy of the original list, rather you are assigning the variable baseList to be the same reference as baseListToValidateAgainst

If you wanted a new copy of the list, try baseListToValidateAgainst.ToList()

Sign up to request clarification or add additional context in comments.

Comments

1

When you set baseList to baseListToValidateAgainst you are not making a copy of the original list; you only create a reference to the original. Any change you make to baseList is done to the baseListToValidateAgainst object.

This will make a copy:

var baseList = baseListToValidateAgainst.ToList();

Moreover, if type B is mutable, creating a copy of the list is insufficient: you need to create copies of individual items as well. This step may not be straightforward, because it relies on existence of a method in B that gives you a copy. For example, if Entities.DDS has a member that makes a copy of the object, you could write this:

var baseList = baseListToValidateAgainst.Select(i => (B)i.Copy()).ToList();

5 Comments

Okay, I did exactly what you suggest in the first code comment and it didn't work.
@BenDonnelly This means that you have situation #2, i.e. I is mutable, and your code modifies it. You need to make copies of objects from the list.
What do you mean by creating a copy of the object?
@BenDonnelly I am assuming that by "it didn't work" you mean that modifications inside your method are visible in the objects of baseListToValidateAgainst. This could happen only when B is a mutable class. You can fix this by giving Entities.DDS a method to "clone" the object (I called it Copy() in my second code example).
Yes I got that, but what I was asking is what the clone method would do, and why? Thanks
-1

Then I modify the baseList variable

No, you haven't modified it. You have neither modified the variable (there is no later assignment to it, which is what modifying the variable would mean) nor have you modified the list that the variable refers to (you have called no methods of List that mutate it, such as Add or Remove), nor have you mutated any of the objects inside of that list (you defined a query that, when that query is executed it will mutate the items in the list that the variable refers to, but you never actually execute that query, so those items are never mutated.

You should avoid side-effect causing queries. They're confusing. If you want to perform some action for all of the items in that list, then use a foreach, that's the proper tool for that specific task:

foreach(var item in baseList)
    item.Value = item.Value.Replace("-", " ").Trim().ToLower();

And now you've successfully mutated the items in that list.

1 Comment

This had no effect, the result is the still the same @Servy

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.