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
How to Unescape and Reescape Strings in .Net
How to Find the Position of a Cursor in a Text Box? C#
C#: How to Add Subitems in Listview
How Does Deferred Linq Query Execution Actually Work
Selecting Attribute Values with HTML Agility Pack
How to Change Currentculture at Runtime
C# - Inconsistent Math Operation Result on 32-Bit and 64-Bit
Visual Studio 2005 Designer Moves Controls and Resizes Form
What's the Least Invasive Way to Read a Locked File in C# (Perhaps in Unsafe Mode)
Modify Xml Existing Content in C#
Local Database, I Need Some Examples
Using String as a Lock to Do Thread Synchronization
Foo.Cmd Won't Output Lines in Process (On Website)
Is Deferred Execution in ASP.NET MVC View a Very Bad Thing
Converting Long String of Binary to Hex C#
Wpf Dispatcher {"The Calling Thread Cannot Access This Object Because a Different Thread Owns It."}