In my current project I’ve written quite a few extension methods (I believe thats the correct term, I’m pretty new to C#) to make the code easier to read and work with.
I’m trying to make an extension method that modifies the list that it’s called on. There’s never an instance where I’d want to get back a new/different list with this method, so calling myList.StackItems() just makes more sense than writing myList = myList.StackItems() and then dealing with the garbage collection of the abandoned original list.
How can I modify a List in place with an extension method? Is it possible?
Sure, you get a reference to the list as a parameter to the extension method, so you can do what you want to it:
public static void StackItems<T>(this List<T> theList) {
// do whatever you want with theList, like swapping first and last elements:
var temp = theList[0];
theList[0] = theList[theList.Count - 1];
theList[theList.Count - 1] = temp;
}
Oh… well… ok then. I was under the impression (for some reason?) that the list wasn’t passed by reference that way? This is a rare area where I feel like C/C++ is easier. You clearly know whats by value and what’s by reference.
x = x + 2;
}
Clearly after running that, x’s value does NOT change outside the method. Assumed lists were the same.
Is there a list somewhere of what is passed by which methods? Or some easy way to remember which is which?
All classes in C# are reference types and are always passed by reference. The only things passed by value (value types) are Enums and structs. Structs include all of the “simple” types like System.Int32 and System.Single (aka int and float).
Reference types (Always passed by reference): Reference types - C# reference | Microsoft Learn
Value types (always passed by value except when using “ref” or “in” keyword): Value types - C# reference | Microsoft Learn
Well all parameters are generally passed by value. However people often confuse the concept of passing by value / passing by reference with the concept of a reference type or a value type. See my answer over here for an explanation. So extension methods still only get the context object passed by value. However that doesn’t mean that you can not modify the object behind a reference type. In integer is a value type, “passed by value”. So the parameter that is copied into the local parameter variable is always just copied.
Keep in mind that you could use extention methods on literal values as well. So an extension method for “int” can never change the original value.
This is a completely pointless method. I just want to show how it could be used and why it wouldn’t make any sense:
public static void Add(this int aVal, int aAdd)
{
aVal += aAdd;
}
42.Add(7);
It should be obvious that you can not “change” the “42” integer literal. This is where passing by reference comes into play. However you can only pass variables by reference. So literal or immediate values can not be passed by reference.
Passing by reference requires the ref or out keyword both in the method definition as well as when calling the method. Ref parameters only accept variables since when passing a variable to a ref parameter you actually pass the memory address of the location where the variable is stored to the method.