Generic Singly-Linked List implementation I'm looking for some feedback regarding my implementation of a generic singly-linked list in C#. I'm also looking for some tips on how to implement other techniques such as using IEnumerable or other .NET interfaces I'm currently not aware of.

Node.cs



using System; 
namespace SinglyLinkedLists
{
    public class Node&lt;T&gt;
    {
        private Node&lt;T&gt; _next;
        private T _data;

        public Node&lt;T&gt; next{
            get { return _next; }
            set { _next = value; }
        }

        public T data{
            get { return _data; }
            set { _data = value; }
        }

        public Node(T newData){
            this._data = newData;
            this._next = null; 
        }

        public static void printNodes(Node&lt;T&gt; head){
            Node&lt;T&gt; currentNode = head;
            while (currentNode != null){
                Console.WriteLine(currentNode.data);
                currentNode = currentNode.next;
            }
        }
    }
}


SinglyLinkedLists.cs

using System; 
namespace SinglyLinkedLists
{
    public class SinglyLinkedLists&lt;T&gt;
    {
        private Node&lt;T&gt; head;
        private Node&lt;T&gt; previous;
        private Node&lt;T&gt; current;
        private Node&lt;T&gt; tail;

        private int numberOfNodes = 0;

        public SinglyLinkedLists()
        {
            head = null;
            previous = null;
            current = null;
            tail = null; 
        }

        public void PrintList(){
            Node&lt;T&gt; current = head;
            while (current != null){
                Console.WriteLine(current.data);
                current = current.next;
            }
        }

        public void AddLast(T data){
            Node&lt;T&gt; newNode = new Node&lt;T&gt;(data);
            if (tail == null){
                head = tail = newNode;
            }
            else{
                tail.next = newNode; 
                tail = newNode; 
            }
            numberOfNodes++;
        }

        public void AddLastTwo(T data){
            Node&lt;T&gt; newNode = new Node&lt;T&gt;(data);

            if (head == null){
                head = newNode; 
            }
            else{
                current = head;
                while (current.next != null){
                    current = current.next; 
                }
                current.next = newNode;
            }
            numberOfNodes++;
        }

        public void RemoveNode(T data){
            Node&lt;T&gt; nodeToRemove = new Node&lt;T&gt;(data);
            current = head;

            if(head.data.Equals(nodeToRemove.data)){
                current = head.next;
                head = current;
            }
            else{
                while (current != null){
                    if (current.data.Equals(nodeToRemove.data)) {
                        previous.next = current.next;
                        current = previous;
                    }
                    else{
                        previous = current;
                        current = current.next;
                    }
                }
            }
            numberOfNodes--;
        }

        public int ListSize(){
            return numberOfNodes;
        }

        public bool InList(T data){
            Node&lt;T&gt; nodeToLookFor = new Node&lt;T&gt;(data);
            Node&lt;T&gt; current = head;
            while (current != null){
                if (current.data.Equals(nodeToLookFor.data)){
                    return true;
                }
                current = current.next;
            }
            return false;
        }

    }
}
A few things that stuck out to me:

You don't gain anything by having the Node class public.  The user of your linked list should only need to be concerned about the data.

It seems very illogical to me to have the Node class printing the LinkedList.  This should more properly be only part of the LinkedList itself.  It would probably be advantageous though for the Node class to override the ToString() method to make it easier to print the data.

From a quick perusal, I couldn't see any use for the previous property except in the RemoveNode method.  I would suggest keeping it local to that method.

A comment explaining the purpose of the AddLastTwo method.  To me it appears to iterate over the list to find the last node, instead of using the last property of the class, like the AddLast.

To me names like AddLast and RemoveNode are over complicated.  If a node isn't being added to the end then it would be an insert operation not an add.  It shouldn't be necessary to tell the user that it's being added to the end.  Likewise the user doesn't need to know that the data is stored in a node, they are simply concerned with removing the data.

When you are using default get and set methods it's much easier to use the default syntax:

public Node&lt;T&gt; next{get;set;}