使用扩展方法扩展非静态类型时,是否在"这个"发生在扩展类的原始实例上,还是返回应用了这些更改的新实例?或者也可以这样做,具体取决于扩展方法的编写方式?
考虑这个示例扩展方法:
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;
}
以下哪种方法可以解决这个问题?
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);
答案 0 :(得分:5)
快速回答......这取决于。
您给出的示例返回AddressEntity
的新实例,但没有理由不能返回相同的实例,这对于链接或完全不同的东西都很方便。
取决于你。
myEntity = myEntity.FromAddressLight(light);
在您的示例中正确使用此方法。
并且myEntity = AddressEntity.FromAddressLight(light);
不起作用,因为你正在调用静态方法而不是实例方法,即使这在静态声明中有点反直觉。
答案 1 :(得分:3)
这有点奇怪作为一种扩展方法(作为"普通"静态方法更有意义)但是这里按照你的行顺序(跳过前两个):
这无济于事。扩展方法返回一个新对象,该对象未分配给任何东西,因此超出范围并被垃圾收集。
这将完全符合您的想法,并且是唯一合理的"使用这种方法的方法。
这是不允许的,因为没有" AddressEntity"传递给函数。不明确(显然你只传递1个参数)或隐式(因为你使用了类型来访问它,而不是对象)。
特别是因为你试图做(3),我不会将这个函数作为扩展方法(它甚至不使用任何AddressEntity字段,那么为什么它采用那种类型?)并且相反,它是一种常规的静态方法。
明确地回答你的问题(标题中):
扩展方法不是特别的,它只有一个隐式参数("这个"参数)所以它在调用它时看起来不错。如果它返回一个新值,您将获得一个新值。如果你修改了"这个"参数,它修改现有的值。它实际上可以做到这两点没有问题。它完全取决于扩展方法的内容。
答案 2 :(得分:1)
一般来说,这是一种非常奇怪的扩展方法。考虑到扩展方法只是语法糖(正如其他人之前提到的那样),普通用户真的会期待发生以下两种情况之一:
我认为第二个是你真正想要的:
public static AddressEntity ToAddressEntity(this AddressLight obj)
{
return new AddressEntity
{
Id = obj.AddressId,
AddressName = obj.AddressName,
// other mapping conversions here
};
}
请记住,扩展方法不是基于返回类型,而是基于this
之后指定的类型。所以在这种情况下你可以做AddressEntity addEntity = SomeAddressLight.ToAddressEntity();
。这也是你没有在任何BCL中看到模式FromSomething()
的原因,因为在扩展方法的情况下,它感觉非常违反直觉。