To my knowledge this
in a extension method is passed as a ref
variable. I can verify this by doing
public static void Method<T>(this List<T> list)
{
list.Add(default(T));
}
List<int> ints = new List<int>(new int[] { 1, 2, 3, 4, 5 });
ints.Method();
My List<int> ints
is now 1, 2, 3, 4, 5, 0
.
However when I do
public static void Method<T>(this List<T> list, Func<T, bool> predicate)
{
list = list.Where(predicate).ToList();
}
List<int> ints = new List<int>(new int[] { 1, 2, 3, 4, 5 });
ints.Method(i => i > 2);
I would expect my List<int> ints
to be 3, 4, 5
but remains untouched. Am I missing something obvious?
Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. Extension methods are static methods, but they're called as if they were instance methods on the extended type.
The extend() method adds all the elements of an iterable (list, tuple, string etc.) to the end of the list.
In object-oriented computer programming, an extension method is a method added to an object after the original object was compiled. The modified object is often a class, a prototype or a type. Extension methods are features of some object-oriented programming languages.
The only difference between a regular static method and an extension method is that the first parameter of the extension method specifies the type that it is going to operator on, preceded by the this keyword.
The this
extension method parameter is passed by value, not by reference. What this means is that upon entering the extension method, you have two variables pointing to the same memory address: the original ints
and the list
parameter. When you add an item to the list inside the extension method, it is reflected in ints
, because you modify an object referenced by both variables. When you reassign list
, a new list is created on the managed heap and the extension method's parameter points to this list. The ints
variable still points to the old list.
Well, when you try to modify property of some class instance you don't even need ref
because you're modifying instance rather then reference to it.
In this example you don't need ref
keyword as you modify property :
class MyClass
{
public int MyProperty { get; set; }
}
static void Method(MyClass instance)
{
instance.MyProperty = 10;
}
static void Main(string[] args)
{
MyClass instance = new MyClass();
Method(instance);
Console.WriteLine(instance.MyProperty);
}
Output : 10
And here you do need ref
keyword because you work with reference and not with instance :
...
static void Method(MyClass instance)
{
// instance variable holds reference to same object but it is different variable
instance = new MyClass() { MyProperty = 10 };
}
static void Main(string[] args)
{
MyClass instance = new MyClass();
Method(instance);
Console.WriteLine(instance.MyProperty);
}
Output: 0
It's same for your scenario, extension methods are the same as normal static methods and if you create new object inside method then either you use ref
keyword (it's not possible for extension methods though) or return this object otherwise the reference to it will be lost.
So in your second case you should use :
public static List<T> Method<T>(this List<T> list, Func<T, bool> predicate)
{
return list.Where(predicate).ToList();
}
List<int> ints = new List<int>(new int[] { 1, 2, 3, 4, 5 });
ints = ints.Method(i => i > 2);
foreach(int item in ints) Console.Write(item + " ");
Output : 3, 4, 5
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With