1

I am writing a game, will have a class just for my collision in the world. I want to pass it two lists in its constructor, one that will contain all the Enemies, and another that will contain all the bullets the player fires.

This is a 2d ship game done in XNA, I should say that, but I felt like posting here because it has more to do with C# ref keyword. If I use the ref keyword in the constructor when passing the Lists into it.

Now if I were to start messing around with the elements in the List, removal and adding of elements, modification etc, would since they were passed by reference make it so that I would never have to re-pass the lists into the class, if the lists themselves are contained in some other class?

public Collsion_manager(ref List<Bullet> bullets_world, ref List<Enemy_class> enemies_world) { } 
4
  • 2
    Hmm... In general I avoid ref. I regard it as a code smell. // List<T> is a reference type to begin with; so I don't see what the additional ref keyword would buy you. // Also - whathaveyoutried.com // Couldn't you have easily tried this out on your own before asking us? Commented Mar 16, 2013 at 3:12
  • 2
    @JimG. there is a reason to use ref for reference types, the semantics are difference between actually creating a new object that you make the ref point to and changing the members of the given list. The former only effects the calling method's local reference, the ladder effects any reference across the entire system that points at that particular List object. Oddly the ref object can be a safety mechanism in a scenario like that (though it doesn't stop you from doing the ladder). Commented Mar 16, 2013 at 3:16
  • @Jimmy Hoffa: Fine - But aren't there more straightforward ways to accomplish those tasks? Commented Mar 16, 2013 at 3:19
  • 1
    @JimG. yeah, I hate ref and out personally, key value pairs for multiple outs as well as new types encapsulating all your members was the way to go for a long time before Tuple's to avoid the ref/out hackery. Commented Mar 16, 2013 at 3:27

1 Answer 1

5

Generally you want to avoid passing a reference type (like List<T>) by ref. You can pass in the List<T>s and call whatever methods you want on it and the changes will carry through fine (like .Add(), .Remove(), .Sort(), etc.). You would only need to pass in the List<T> once (say in the constructor) and the reference will stay valid for the lifetime of the object even if you don't use ref.

The difference it makes is that when you pass the List<T> by ref, you are passing a reference (pointer) to the variable argument, not the object. This will only make a difference if you want to assign a new List<T> to the variable.

I made a little program that illustrates this difference.

class Program { static void Main(string[] args) { List<int> listA = new List<int> { 1, 2, 3 }; List<int> listB = new List<int> { 1, 2, 3 }; Update(listA); UpdateRef(ref listB); Console.WriteLine("listA"); foreach (var val in listA) Console.WriteLine(val); Console.WriteLine("listB"); foreach (var val in listB) Console.WriteLine(val); } static void Update(List<int> list) { list = new List<int>() { 4, 5, 6 }; } static void UpdateRef(ref List<int> list) { list = new List<int>() { 4, 5, 6 }; } } 

Here is the output produced by the program:

listA 1 2 3 listB 4 5 6 

Notice how listB contains the new List<T> but listA doesn't. This is because we had a reference to the variable listB.

Sign up to request clarification or add additional context in comments.

3 Comments

Note, the purpose of ref and out both is for multiple returns. If you have one return value, don't use ref or out, just return that it. And better practice for multiple returns with modern .net is to return a tuple and just never use out or ref
That doesn't matter for reference types though which is what the question is about. For value types yes, it can enable a method to return multiple values.
Value types can be returned just fine, there's no reason to use public void AddOne(ref int i) instead of public int AddOne(int i), usage being i = AddOne(i); ref and out only exist for multiple returns, ref is needed because you can't out a value type

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.