Reputation: 3621
When you extend a non-static type with an extension method, does the work performed on "this" happen to the original instance of the extended class, or does it return a new instance with those changes applied? Or can it do either, depending on how the extension method is written?
Consider this example extension method:
public static AddressEntity FromAddressLight(this AddressEntity addressEntity, AddressLight addressLight)
{
if (addressLight == null)
{
return null;
}
var result = new AddressEntity
{
Id = addressLight.AddressId,
AddressName = addressLight.AddressName,
// other mapping conversions here
};
return result;
}
Which of the following ways of calling this would work?
AddressLight light = new AddressLight(); // assume constructor populates this
AddressEntity myEntity = new AddressEntity(); // this constructor does not populate anything
myEntity.FromAddressLight(light); // Will this cause myEntity take on the value of "result" in the extension method?...
myEntity = myEntity.FromAddressLight(light); // ... or is this needed to copy "result" into myEntity?
// ... and why is this not something Visual Studio allows? Does this not become a static member of the extended class?
myEntity = AddressEntity.FromAddressLight(light);
Upvotes: 2
Views: 2448
Reputation: 525
This is pretty odd as an extension method, in general. Consider that the extension method is just syntactic sugar (as was previously mentioned by others), and that a normal user would really be expecting one of two things to happen:
I think number two is what you really want:
public static AddressEntity ToAddressEntity(this AddressLight obj)
{
return new AddressEntity
{
Id = obj.AddressId,
AddressName = obj.AddressName,
// other mapping conversions here
};
}
Remember that extension methods are not based on the return type but on the type specified after this
. So in this case you can just do AddressEntity addEntity = SomeAddressLight.ToAddressEntity();
. This is also the reason you don't see the pattern FromSomething()
in any of the BCL because in the case of an extension method it feels very counterintuitive.
Upvotes: 2
Reputation: 13079
Quick Answer... It Depends.
The example you give returns a new instance of AddressEntity
but there's no reason it can't return the same instance which is handy for chaining or something completely different.
It's up to you.
myEntity = myEntity.FromAddressLight(light);
is the correct use of this method in your example.
And myEntity = AddressEntity.FromAddressLight(light);
doesn't work because you're calling a static method not an instance method even though this is a little counter-intuitive given the static declaration.
Upvotes: 5
Reputation: 61379
Thats kind of odd as an extension method (makes more sense as a "normal" static method) but here goes, In order of your lines (skipping the first two):
This will do nothing. The extension method returns a new object, which is not assigned to anything, and so falls out of scope and is garbage collected.
This will do exactly what you think, and is the only "reasonable" way to use this method.
This isn't allowed because there is no instance of "AddressEntity" being passed to the function. Not explicitly (obviously you only pass 1 argument) or implicitly (because you used the type to access it, not an object).
Especially because you are trying to do (3), I would not have this function as an extension method (it doesn't even use any of the AddressEntity field, so why does it take that type?) and have it be a normal static method instead.
To answer your question (in the title) explicitly:
An extension method isn't anything special, it just has an implicit argument (the "this" argument) so it looks nice when calling it. If it returns a new value, you'll get a new value. If you modify the "this" argument, it modifies the existing value. It could actually do both with no problem. It completely depends on the content of the extension method.
Upvotes: 3