4

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;
            }
        }
     }
2
  • 3
    You can also consider making your private class implement a public interface (that only exposes the functionality you want exposed) . Create a factory method that creates your class instances, but returns them as interface references
    – Flydog57
    Aug 6 at 6:01
  • @HansKesting not working. It also prevents the enclosing class from creating nested class instance.
    – Yasir
    Aug 6 at 6:15

1 Answer 1

3

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.

Not the answer you're looking for? Browse other questions tagged or ask your own question.