-4

I have a class, Solution. I use this class as a List which I don't want to grow unnecessarily.

I search the list to get a preexisting entry and return that -or- create a new entry if need be:

var s0 = _solutions.Where(x => x.strtId == strtNodeId && x.endId == endNodeId).ToList();

However, Linq will actually create new instances when where is true. But, as you might already see, that is not what I want.

The combination of x.startNode && x.endNode is unique in all instances of _solution

At the end what I need is the reference to the one instance of _solution being searched for, if it already exists.

But what can I do aside from creating my own for loop/s?

Thanks.

Steve
  • 905
  • 1
  • 8
  • 32
  • 3
    What makes you think that s0 will contain new instances of those items that you've searched for ? – Frederik Gheysels Nov 10 '16 at 16:28
  • 3
    It's creating a new list with the same elements from the old list. It isn't creating new elements. If this doesn't address your question, I'm unclear on what the issue is. –  Nov 10 '16 at 16:29
  • 1
    I don't really understand what you're saying. What's being created? You're creating a `List` at the end, but it sounds like you're talking about new instances of `T` being created. – itsme86 Nov 10 '16 at 16:29
  • 1
    `Where` is definitely not creating new instances of `T` – Jonesopolis Nov 10 '16 at 16:31
  • 3
    If `_solutions` is an `IEnumerable`, and if `Solution` is a reference type (`class`, not `struct`), then it is not correct that new instances of `Solution` are created! You just use references to the existing instances of `Solution`, that are "yielded" from the `IEnumerable<>`. – Jeppe Stig Nielsen Nov 10 '16 at 16:32
  • Do you mean you want to throw away members from your `List<>` called `_solutions`, rather than creating a new `List<>` with the `.ToList()`? – Jeppe Stig Nielsen Nov 10 '16 at 16:36
  • If I check _solution.Count() before and after linq, linq has grown _solution by 1 where where is true. Otherwise where where is false the count has not changed. What linq is returning is copies of the original. Any tips on how to see the memory reference numbers or address of the instances to debug down to that level? – Steve Nov 10 '16 at 16:38
  • 1
    Your premise must be wrong; if the `List<>` is augmented, it happens somewhere else. You can use `System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(sol)` where `sol` is a `Solution` (reference type) to get a kind of "reference number". Or if you have two, check `(object)sol1 == (object)sol2`. These expressions can be simplified if your class does not override `Equals` and `GetHashCode` and does not overload `operator ==`. – Jeppe Stig Nielsen Nov 10 '16 at 16:45
  • @JeppeStigNielsen. Found it. You were right. Would you want to post something of an answer? – Steve Nov 10 '16 at 17:07

4 Answers4

1

You may want to use Single instead of Where.

You can even use SingleOrDefault if you're not sure the element exists in the collection.

Kilazur
  • 3,089
  • 1
  • 22
  • 48
1

I think you are trying to create a class factory out of a list, where a new instance will be created if one doesn't exist or return a singleton instance if one does exist?

In which case, forget list and create a static class factory instead which updates it's internal list with newly created class instances.

Ross Miller
  • 656
  • 3
  • 9
  • That sounds about right – Steve Nov 10 '16 at 16:39
  • Your's is the best idea but I'm not sure I want to go to that effort at this time. Would you say this is a fair example? http://stackoverflow.com/questions/515269/factory-pattern-in-c-how-to-ensure-an-object-instance-can-only-be-created-by-a I have to have one constructor that actually starts by receiving an instance of the same class. This constructor does a copy of the instance sent to it to create the new instance. – Steve Nov 10 '16 at 17:14
1

Promoted from comments:

If _solutions is an IEnumerable<Solution>, and if Solution is a reference type (class, not struct), then it is not correct that new instances of Solution are created! You just use references to the existing instances of Solution, that are "yielded" from the IEnumerable<>.

Your premise must be wrong; if the List<> is augmented, it happens somewhere else. You can use System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(s‌​ol) where sol is a Solution (reference type) to get a kind of "reference number". Or if you have two, check (object)sol1 == (object)sol2. These expressions can be simplified if your class does not override Equals and GetHashCode and does not overload operator ==.

Jeppe Stig Nielsen
  • 60,409
  • 11
  • 110
  • 181
0

Why not do this or I don't understand you correctly.

var result = _solutions.FirstOrDefault(x => x.strtId == strtNodeId && x.endId == endNodeId);

var someValue = result?.SomeProperty;
mybirthname
  • 17,949
  • 3
  • 31
  • 55