How to Get an Extension Method to Change the Original Object

How can I get an extension method to change the original object?

You have to modify the contents of the List<string> passed to the extension method, not the variable that holds the reference to the list:

public static void ForceSpaceGroupsToBeTabs(this List<string> lines)
{
string spaceGroup = new String('.', 4);
for (int i = 0; i < lines.Count; i++)
{
lines[i] = lines[i].Replace(spaceGroup, "T");
}
}

How can I get an extension method to change the original object in Dart?

It would have been possible to change the original object if its properties were not final. This is not the case for LatLngBounds.southwest and LatLngBounds.northeast.

Generic Extension Method for change value of any variable or object

What you want is impossible, as an extension-method allways works on a specific instance of a type. As every other method as well, a method can not change the instance to be something different (which would mean reference another instance), it can only modify that instance by calling any of its members.

If you want to know why it is forbidden to use ref on an extension-method, look this similar question: Impossible to use ref and out for first ("this") parameter in Extension methods?.

On the other hand you can do that with normal methods using the ref-keyword, though.

public static void Set<T>(ref T instance)
{
instance = new Whatever(...);
}

Now you may be able to use this:

var n = 0;
TheClass.Set(ref n);

However if all you want to do in that method is replacing one reference by another one, why not just use this instead?

var n = 0;
n = 1;

C# Replace value of original string in extension method

Strings are immutable.

That's fundamentally impossible.

Extension method not setting value

I suggest a small change to follow a fluent interface pattern. Instead of void, return the new product instead. Don't use ref, that is weird.

public static class ProductExtension
{
public static Product FixProduct(this Product input)
{
return new Product
{
Name = input.Name.ToUpper(),
Id = input.Id
}
//product.Name is now UPPERCASE
}
}

Then use it like this:

static void Main(string[] args)
{
var p = new Product()
{
ProductId = 1,
Name = "steve"
}
.FixProduct();
System.Console.WriteLine(p.Name);
}

A neat advantage of this approach is (if you think you will need it) you can support several product classes while preserving their precise type, e.g.:

public static class ProductExtension
{
public static T FixProduct<T>(this T input) where T: Product, new
{
return new T
{
Name = input.Name.ToUpper(),
Id = input.Id
}
}
}

Now you could use it on any derived product class while keeping exactly the same syntax.

class DeluxeProduct : Product
{ }

static void Main()
{
var p = new DeluxeProduct
{
Id = 1,
Name = "Steve"
}
.FixProduct();
Console.WriteLine(p.GetType().Name)); //outputs "DeluxeProduct"
}

Now on the other hand, if all you want to do is "fix" the product's name, you could just wrap it in a property.

class Product
{
private string _name;

public int Id { get; set; }

public string Name
{
get { return _name; }
set { _name = value.ToUpper(); } //Automatically "fix" it the moment you set it
}
}

...and then you don't need an extension method at all.

How to add an extension method to List of custom object to covert them to a new list

You can write your own extension method

public static class LinqExtension
{
public static IEnumerable<ViewModel> ToViewModel(this IEnumerable<Entity> source)
{
// your own conversion from Entity to ViewModel
return result;
}
}

Then you are able to use EntityList.ToViewModel()

Why can't I update the value of a string in an extension method?

The problem here is that although the string is a reference type, when you pass a parameter to a method that reference is copied. So a new variable is created that points to the same object in memory. When you make that variable point to a new object, it doesn't affect the original object.

Here is an example to clarify what I mean:

var foo = "foo";
var bar = foo;

bar = "bar";

We create a string and store it's reference in the foo variable. Then we create a bar variable and store the reference of foo in it. This is a copy of the reference, now 2 variables are pointing to the same object.

When we create a new string and assign it to bar, it doesn't affect foo. Now the bar just holds a reference to a different object.

There is a way to make it so that the original parameter is modified and reference is not copied, and it can be done by using ref parameters. But as far as I know ref modifier is not supported for the first parameter of extension methods.

updating value by extension method without return

Your problem appears to be caused by this line:

entity = entity.Load(x => (IList<TItem>)x.GetType().GetProperties().ToList().Find(c => c.PropertyType == typeof(IList<TItem>)).GetValue(x));

Now that you have posted the contents of the Load method, we can see that it, in turn, calls:

T reAttached = session.Merge<T>(entity);
// ...
return reAttached;

My knowledge of Hibernate is limited, but chances are good that, if not always, at least sometimes, the call to Merge will return a reference to a different object instance from what is passed in.

This has the cascading effect that, in your extension method, the local variable entity gets reassigned to a completely new object. Because the entity reference variable is a copy of the c1 reference variable (and not a reference to it), when it gets reassigned, the change is not reflected in the c1 variable. Your c1 variable effectively still points to the original entity instance before it got changed by the call to BaseClass.Load().

Basically, as others have already stated, to code an extension method that doesn't need to return an entity reference, you have to limit yourself to changing the state of the entity object through its methods/properties. You can't actually change the object reference completely, because this will never be reflected outside the method call.

In your case, it looks like you should stick with your original extension method that returns the entity reference.


Relevant reading: Parameter passing in C#

In particular, the section Sidenote: what is the difference between passing a value object by reference and a reference object by value? applies to what is happening here.



Related Topics



Leave a reply



Submit