How do I get the algorithm to act on the actual stack that gets passed in?
You do not need a ref parameter here since Stack<T> is a reference type and you are not trying to re-assign the reference itself.
References are by default passed by value but that value (the reference) points to the same object on the heap, in other words you have two references pointing to the same object which is fine - all operations will be executed on the original Stack<T> object.
Edit:
In light of your comment I suggest you redesign to not modify the original Stack<T> which is troublesome to begin with:
public static IEnumerable<T> Shuffle<T>(Stack<T> source) { Random rng = new Random(); T[] elements = source.ToArray(); // Note i > 0 to avoid final pointless iteration for (int i = elements.Length - 1; i > 0; i--) { // Swap element "i" with a random earlier element it (or itself) int swapIndex = rng.Next(i + 1); T tmp = elements[i]; elements[i] = elements[swapIndex]; elements[swapIndex] = tmp; } // Lazily yield (avoiding aliasing issues etc) foreach (T element in elements) { yield return element; } }
Now you can just use it like this:
foreach (var item in Doshuffle.Shuffle(gameDeck)) { System.Console.WriteLine(item.cardName); }
Also be careful with your use of Random - you might want to pass it in. At this point you can use Jon Skeet's Shuffle implementation instead of your own - it's better to reuse than reinvent.
Final Edit:
It looks like you just want to shuffle your Stack<T> in place -use an extension method instead:
public static void Shuffle<T>(this Stack<T> source) { Random rng = new Random(); T[] elements = source.ToArray(); source.Clear(); // Note i > 0 to avoid final pointless iteration for (int i = elements.Length - 1; i > 0; i--) { // Swap element "i" with a random earlier element it (or itself) int swapIndex = rng.Next(i + 1); T tmp = elements[i]; elements[i] = elements[swapIndex]; elements[swapIndex] = tmp; } foreach (T element in elements) { source.Push(element); } }
Now you can just do:
gameStack.Shuffle();
refbut I'd almost say leave it in. The combination of returning anIEnumerableand modifying the incoming collection is rather fishy.