views:

151

answers:

3

I need some clarification. Are these two methods the same or different? I get a little bit confused about when the reference to an object passed in a parameter by value is updated and when a new one is created. I know if that assignment creates a new reference, but what about changing a property? Will both of these methods update the field "_someObjectList" the same way?

 public class SomeObject{
     public Guid UniqueKey { get; set; }
     public object SomeProperty{ get; set; }
 }

 public class SomeObjectListWrapper{

    public SomeObjectListWrapper(List<SomeObject> someObjectList){
        _someObjectList = someObjectList;
    }

    private readonly List<SomeObject> _someObjectList;

    public void ReplaceItemPropertyValue1(Guid itemUniqueKey, object propertyValue)
    {

        List<int> resultIndices = new List<int>();
        for (var i = 0; i < _someObjectList.Count(); i++)
        {
            if (_someObjectList[i].UniqueKey == itemUniqueKey)
                resultIndices.Add(i);
        }

        if (resultIndices.Count != 1)
            throw new Exception(
                "just pretend this is the same exception as Single() throws when it can't find anything");
        _someObjectList[resultIndices[0]].SomeProperty = propertyValue;
    }

    public void ReplaceItemPropertyValue2(Guid itemUniqueKey, object propertyValue)
    {
        _someObjectList.Single(x=>x.UniqueKey==itemUniqueKey).SomeProperty=propertyValue;
    }
}
A: 

They may do the same thing depending on the data in your list. ReplaceItemPropertyValue2 uses the Single method which will throw an exception if itemUnqiueKey is not found or found more than once.

But as long as itemUniqueKey can't appear more than once in the list, the two functions should accomplish the same task.

Matthew Manela
+2  A: 

Because SomeObject is a class (ie. a reference type), both ReplaceItemPropertyValue methods are updating the same object as was inserted into the list and will be retrieved from the list later. (If SomeObject was a struct/value type, the compiler would prevent you from updating an rvalue/return value [1].)

As a minor side-note, your two methods are not actually identical. The Single method raises an exception if there is more than one matching item in the sequence. To properly match the behaviour, use First instead.


  1. "rvalue" is not actually short for "return value," it just happens that in this case your rvalue is a return value, which is why I specified both options.
Zooba
I edited the posted code and I think it should now reflect Single() instead of First(). Please advise. Thank you for your help. If you have a moment could you please explain or provide a link about your comment (if SomeObject was a struct). I have Dictionary class (I believe deriving from ICollection<KeyValuePair<,>>) in mind as I ask this.Thanks again.
smartcaveman
The answer at http://stackoverflow.com/questions/2414906/what-are-the-differences-between-value-types-and-reference-types-in-c/2414954#2414954 briefly explains the difference. (Note that part one of the 'answer' given in the question is wrong.) A `Dictionary<Guid,SomeObject>` is probably what you want here, rather than a `List<SomeObject>`.
Zooba
A: 

Both may be same.

The algorithm in the for loop set the object when key matches and then breaks out.

While the LINQ statement will set the object to all entries whose key match. It depends if your collection has same key entered more than once.

Nayan