Basic domino game architecture
I think this is a good exercise for trying out OOP design.  When I was learning OOP I found that working with real-life objects helped a lot and slowly I started getting use to objects that represented abstract concepts.  In this example you have a mixture, real-life dominoes and abstract concepts such as the 'Game' object.

The Domino Class is a good candidate for an immutable object.  It is often a good idea to create immutable objects when you can as this can be a powerful mechanism to stop erroneous state from being accidentally recycled.

There seems to be quite a bit of duplication going on within the Domino Class.  This can sometimes lead to confusion when debugging.  If you are debugging, and the name of a domino says "3,2" but the Head and Tail show 4 and 1 then you are left not sure about what happened.  Best to try and avoid this from happening.

I think it is also a good idea to make sure that all the logic that represents dominoes is wrapped up in the Domino class.  This will help to avoid abstraction leakage.  It is fairly obvious that a domino has a head and a tail and this is exposed via your properties but it may not be obvious how the domino name should be formatted (e.g. should it use a comma 3,4 or a colon 3:4) or how a domino's weight is determined.  If you have to evaluate the weight of a domino outside of the domino class then this might be considered as abstraction leakage.

Putting these concepts together, here is how I would program the Domino Class:

// Represents a tile used in a domino game.
// This class is designed to be immutable.
public class Domino
{
    // Private constructor means that dominos can
    // only be crated from a static method in this class.
    private Domino(string name, int weight)
    {
        // domino name can either be in the format H,T or H:T
        string[] nameParts = name.Split(',', ':');
        if (nameParts.Length != 2)
        {
            throw new ArgumentException("Invalid name format.");
        }

        try
        {
            Head = Int32.Parse(nameParts[0]);
            Tail = Int32.Parse(nameParts[1]);
        }
        catch
        {
            throw new ArgumentException("Invalid name format.");
        }

        Weight = weight;
    }

    // The properties of the domino class have a private set
    // because this class is designed to be immutable.
    public int Head { get; private set; }
    public int Tail { get; private set; }
    public int Weight { get; private set; }

    public bool IsDouble { get { return (Head == Tail); } }

    // Avoid duplicating the head and tail values by
    // generating the name every time it is needed.
    // This will be quick enough that it won't impact
    // performance.  Only worry about performance once
    // it starts to become a problem.
    public string Name { get { return Head.ToString() + "," + Tail.ToString(); } }

    public override string ToString() { return Name; }

    // Returns a full collection of shuffled dominos
    // this static method is part of the domino class
    // and so it can use the private constructor.
    public static DominoCollection GetAll()
    {
        string[] tiles = new string[]
        {
            "0,1","0,2","0,3","0,4","0,5","0,6",
            "1,2","1,3","1,4","1,5","1,6",
            "2,3","2,4","2,5","2,6",
            "3,4","3,5","3,6",
            "4,5","4,6",
            "5,6",
            "0,0","1,1","2,2", "3,3", "4,4","5,5","6,6"
        };

        DominoCollection dominos = new DominoCollection();
        for (int i = 0; i &lt; tiles.Length; i++)
        {
            dominos.Add(new Domino(tiles[i], i));
        }

        dominos.Shuffle();
        return dominos;
    }
}


I would define the DominoCollection class to make as much use of the built-in features as possible by inheriting it from the generic collection class:

public class DominoCollection : Collection&lt;Domino&gt;
{
    // shuffels the dominos in this collection
    public void Shuffle()
    {
        Random r = new Random();

        int n = Count;
        while (n-- &gt; 1)
        {
            int k = r.Next(n + 1);
            Swap(k, n);
        }
    }

    // swap the domino in index 1 with the domino in index 2
    private void Swap(int i1, int i2)
    {
        Domino temp = this[i1];
        this[i1] = this[i2];
        this[i2] = temp;
    }
}


Now you can get the full set of dominoes like this:

DominoCollection dominos = Domino.GetAll();


This still might not be considered ideal and there maybe some who suggest that the Domino.GetAll() method should not be a static method of Domino but instead should be in the collection class (similar to your original code) but at least you will have considered the alternatives and thought about the concept of abstraction leakage.