Wang_TWJ
Wang_TWJ

Reputation: 63

Confusion about extension method

I have a question about extension method.I write following code:

public static List<TxCurve> Sort(this List<TxCurve> fubanCenters, List<TxCurve> sortedPillar, TxCurve roadCenter)
{
    List<TxCurve> sortedCurve = new List<TxCurve>();
    // do something ...

    fubanCenters = sortedCurve; //change fubanCenters
    return fubanCenters;
}

use the extension method:

//use extension method
centers.Sort(sortedPillar, roadCenter);

But after execute above code, the centers doesn't change, Why? please tell me, thank you.

Upvotes: 0

Views: 76

Answers (2)

Chris Schaller
Chris Schaller

Reputation: 16564

Assuming that the // do something... does not actually affect the list that is being extended, we refer to this type of method as a Function and may even refer to it as Immutable.

Because this method performs an operation and returns the result, when you call the function, you will need to save the results before you can use them, as suggested by @Collen

List<TxCurve> sortedCenters = centers.Sort(sortedPillar, roadCenter); 

If instead your intention was for the Sort to act on the list, then you could change the extension method definition as either of the following:

public static void Sort(this List<TxCurve> fubanCenters, List<TxCurve> sortedPillar, TxCurve roadCenter)
{
    List<TxCurve> sortedCurve = new List<TxCurve>();
    // do something ...

    fubanCenters.Clear();
    fubanCenters.AddRange(sortedCurve); //change fubanCenters
}

or if you intend to support chaining syntax, you could also return a reference to the extended list:

public static List<TxCurve> Sort(this List<TxCurve> fubanCenters, List<TxCurve> sortedPillar, TxCurve roadCenter)
{
    List<TxCurve> sortedCurve = new List<TxCurve>();
    // do something ...

    fubanCenters.Clear();
    fubanCenters.AddRange(sortedCurve); //change fubanCenters
    return fubanCenters;
}

The reason that fubanCenters = sortedCurve; does not work is that in the context of the extension method the vairable called fubanCenters is only a reference to the object, it is not a pointer to the actual object.
By assigning a new value to the fubanCenters variable, you are actually replacing the previous reference with a reference to the new object.

To prove this phenonenon, with your existing code the following will evaluate to false. //use extension method var result = centers.Sort(sortedPillar, roadCenter); var areEqual = result == centers;

Upvotes: 3

VillageTech
VillageTech

Reputation: 1995

The question was: why? So, the fubarCenters is the pointer parameter, represented as local variable. You replaced value of this parameter by sortedCurve only locally, it means it starts pointing the new list only locally.

To make this change visible outside, try this:

public static List<TxCurve> Sort(this List<TxCurve> fubanCenters, List<TxCurve> sortedPillar, TxCurve roadCenter)
{
    List<TxCurve> sortedCurve = new List<TxCurve>();
    // do something ...

    fubanCenters.Clear();
    fubanCenters.AddRange(sortedCurve); //change fubanCenters
    return fubanCenters;
}

Upvotes: 1

Related Questions