I am implementing a Linked list in C#. I created a Node class and a MyLinkedList class. Node class implements the node having properties Key and Next. MyLinkedList class implements all the operations such as Insert, Find, Update, Remove etc and two properties Head and Count.
I don't want the user to create Node instances from outside of the MyLinkedList class so I nested the Node class inside MyLinkedList class making it private. Now, in the implemetation of Find method I am unable to return the Node type. I am also not able to give public access to Head property of outer class which is also a Node instance.
Summary: Basically, the problem is I want to prevent user from making an object of nested private class anywhere outside of it's enclosing class but it also limits the enclosing class ability to return it's nested private class' instance in the process.
public class MyLinkedList<T>
{
public Node<T> Head { get; set; } //Error: Inconsistent accessibility: property type 'MyLinkedList<T>.Node<T>' is less accessible than property 'MyLinkedList<T>.Head'
public int Count { get; set; }
public MyLinkedList()
{
this.Head = null;
this.Count = 0;
}
public Node<T> Find(T value)//Error: Inconsistent accessibility: property type 'MyLinkedList<T>.Node<T>' is less accessible than method 'MyLinkedList<T>.Find(T)'
{
Node<T> curr = this.Head;
while (!(curr is null) && !curr.Data.Equals(value))
{
curr = curr.Next;
}
if (curr == null) return null;
return curr;
}
private class Node<K>
{
public K Data { get; set; }
public Node<K> Next { get; internal set; }
public Node(K data)
{
this.Data = data;
this.Next = null;
}
}
}
I would introduce an interface INode<K>
, and allow outside code to only access nodes through the interface.
public interface INode<K>
{
K Data { get; set; }
INode<K> Next { get; }
}
Notice that Next
is not publicly settable, since you have an internal set
in your implementation, which I interpret as you don't want outside code to set it.
This is how you can implement it:
private class Node<K>: INode<K>
{
public K Data { get; set; }
public Node<K> Next { get; internal set; }
INode<K> INode<K>.Next => Next;
public Node(K data)
{
this.Data = data;
this.Next = null;
}
}
Then you can change all the public methods of MyLinkedList
to return INode<T>
.
For Head
, you can use a private field of the concrete type Node<T>
, and have a public property of the interface type returning the field. And I'm not very sure why you are allowing everyone to set your linked list's Count
private Node<T> head; // access this field in your implementation instead of the Head property
public INode<T> Head => head;
public int Count {
// compute count here...
// or make the setter private
}
This does meant that outside code won't be able to set the Head
. If you really want to, you can add a setter for Head
with a cast:
public INode<T> Head {
get => head;
set => head = (Node<T>)value;
}
But this is assuming that no one would implement the interface with their own classes and try to set Head
to their own implementation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With