I need a LinkedList
but unfortunatelly the one that the .NET provides didn't have the functionality I was looking for (not working with linq and the LinkedListNode is sealed). I created a replacement that works similar but is linq-compatible.
The main class is a LinkedObject<T>
that might be used on it's own but is better suited to be used by composition and should provide all the functionality of a chain:
[DebuggerDisplay("Value = {Value?.ToString()}")]
class LinkedObject<T>
{
private LinkedObject<T> _previous;
private LinkedObject<T> _next;
public LinkedObject() {}
public LinkedObject(T value)
{
Value = value;
}
public LinkedObject<T> Previous
{
get { return _previous; }
set
{
_previous = value;
value._next = this;
}
}
public LinkedObject<T> Next
{
get { return _next; }
set
{
_next = value;
value._previous = this;
}
}
public T Value { get; set; }
// or maybe precessors?
public IEnumerable<LinkedObject<T>> Before
{
get
{
var item = this;
while (item != null)
{
yield return item;
item = item.Previous;
}
}
}
// or maybe successors?
public IEnumerable<LinkedObject<T>> After
{
get
{
var item = this;
while (item != null)
{
yield return item;
item = item.Next;
}
}
}
public void Remove()
{
_previous.Next = _next;
_next.Previous = _previous;
_previous = null;
_next = null;
}
}
Some custom object would use it like this (my real linked-object has a few more additional properties then this simple example):
class Word
{
private readonly LinkedObject<Sentence> _linkedObject;
public Word()
{
_linkedObject = new LinkedObject<Sentence>(this);
}
public string Value
{
get { return _linkedObject.Value; }
set { _linkedObject.Value = value; }
}
public WordPrevious
{
get { return _linkedObject.Previous.Value; }
set { _linkedObject.Previous = value._linkedObject; }
}
public Word Next
{
get { return _linkedObject.Next.Value; }
set { _linkedObject.Next = value._linkedObject; }
}
public IEnumerable<Word> Before
{
get { return _linkedObject.Before.Select(x => x.Value); }
}
public IEnumerable<Word> After
{
get { return _linkedObject.After.Select(x => x.Value); }
}
}
Example (I use a loop to create the real chain):
var foo = new LinkedObject<string>
{
Value = "foo",
Next = new LinkedObject<string>
{
Value = "bar",
Next = new LinkedObject<string>() { Value = "baz" }
}
};
// foo, bar, baz
foo.Next.Remove(); // foo, baz
1 Answer 1
Rule your own Find
extension method instead of redoing it all over again.
public static LinkedListNode<T> Find<T>(this LinkedList<T> list, Predicate<T> pred)
{
var node = list.First;
while (node != null)
{
if (pred(node.Value))
{
return node;
}
node = node.Next;
}
return null;
}
-
\$\begingroup\$ Oh, was this simple ;-) I guess I have to rethink my idea... \$\endgroup\$t3chb0t– t3chb0t2016年02月13日 08:38:03 +00:00Commented Feb 13, 2016 at 8:38
LinkedList
? Everything I'm testing in VS2015 is working for me. \$\endgroup\$LinkedListNode
so after you've got something withWhere
etc. you're left without the possibility to useNext
orPrevious
... you'd need to do another search with theFind
method to get theLinkedListNode
again. \$\endgroup\$word.After.Last().Next = new Word()
or any other place. You can add/insert items where ever you want by only acting on the items themself that build the actuall list instead of being held by such. \$\endgroup\$List
specific methods in first place? Sounds a reasonable trade for me. \$\endgroup\$