无法在扩展方法中使用ref和out作为第一个(“this”)参数?

时间:2022-08-02 21:03:15

Why is it forbidden to call Extension Method with ref modifier?

为什么禁止使用ref修饰符调用Extension Method?

This one is possible:

这个是可能的:

public static void Change(ref TestClass testClass, TestClass testClass2)
{
    testClass = testClass2;
}

And this one not:

这不是:

public static void ChangeWithExtensionMethod(this ref TestClass testClass, TestClass testClass2)
{
    testClass = testClass2;
}

But why?

但为什么?

4 个解决方案

#1


19  

You have to specify ref and out explicitly. How would you do this with an extension method? Moreover, would you really want to?

您必须明确指定ref和out。你会如何使用扩展方法执行此操作?而且,你真的想要吗?

TestClass x = new TestClass();
(ref x).ChangeWithExtensionMethod(otherTestClass);
// And now x has changed?

Or would you want to not have to specify the ref part, just for the first parameter in extension methods?

或者您是否希望不必指定ref部分,仅用于扩展方法中的第一个参数?

It just sounds weird to me, to be honest, and a recipe for unreadable (or at least hard-to-predict) code.

对我而言,这听起来很奇怪,说实话,以及不可读(或至少难以预测)代码的配方。

#2


5  

I agree with the answers from Jon Skeet et al. about how allowing "ref this" extension methods could make the code more obscure. But if you look at some namespaces in the .Net Framework, it is common for a method invoked on a struct to alter it.

我同意Jon Skeet等人的回答。关于如何允许“ref this”扩展方法可以使代码更加模糊。但是如果你看一下.Net Framework中的一些命名空间,在结构上调用的方法通常会改变它。

Take for example the System.Drawing structs (Point, Rectangle, etc). Each of these has methods (e.g. Offset, Inflate, etc) that mutate the struct itself. I'm not saying this is a good idea, in fact I personally find it very annoying that Offset, Inflate, etc mutate the structs themselves instead of returning new ones, and I know some of you are opposed to the idea of mutable structs in general.

以System.Drawing结构(Point,Rectangle等)为例。其中每一个都有改变结构本身的方法(例如Offset,Inflate等)。我不是说这是一个好主意,事实上我个人觉得Offset,Inflate等变异结构本身而不是返回新结构非常烦人,我知道你们中有些人反对可变结构的想法一般。

I doubt there are any cases where invoking a method of a reference type will change the reference (unless it's with the String class, where I can imagine there might be some compiler magic to switch references to perform interning, etc). So it makes sense to prevent "this ref" from being used with reference types, because changing a reference would be a completely non-standard side-effect of calling a method.

我怀疑在任何情况下调用引用类型的方法都会改变引用(除非它与String类有关,我可以想象可能会有一些编译器魔术来切换引用以执行实习等)。因此,防止“this ref”与引用类型一起使用是有意义的,因为更改引用将是调用方法的完全非标准的副作用。

But in regards to structs, allowing "this ref" would not significantly decrease code readability any more than Rectangle.Inflate, etc, and it would provide the only means to "simulate" that kind of behavior with an extension function.

但是对于结构体,允许“this ref”不会显着降低代码可读性,而不仅仅是Rectangle.Inflate等,它将提供使用扩展函数“模拟”这种行为的唯一方法。

Just as a side-note, here is one example where "this ref" might be useful, and IMHO still readable:

正如旁注,这里有一个例子,其中“这个参考”可能有用,恕我直言仍然可读:

void SwapWith<T>(this ref T x, ref T y) {
   T tmp = x; x = y; y = tmp;
}

#3


3  

I agree that it useful for struct

我同意它对struct很有用

So I want to propose that for making extension method for struct. this keyword should always pass struct by reference

所以我想建议为struct创建扩展方法。此关键字应始终通过引用传递struct

class always pass by reference anyway. And whenever we create extension method we want it to behave like a real method. So real method of class and struct can modified its value. Extension method should be able to too

无论如何,班总是通过引用传递。每当我们创建扩展方法时,我们希望它表现得像一个真正的方法。所以类和结构的真正方法可以修改它的值。扩展方法也应该能够

#4


1  

This would mean that calling myObject.ChangeWithExtentionMethod(otherObject) would actually have the potential to change myObject's value. IMO, that wouldn't make for very readable code when you can instead achieve the desired effect by using a regular non-extension method with a ref.

这意味着调用myObject.ChangeWithExtentionMethod(otherObject)实际上有可能改变myObject的值。 IMO,当你可以通过使用带有ref的常规非扩展方法来实现期望的效果时,这不会产生非常易读的代码。

EDIT: My point is, the method call should require you to use the ref keyword any time that you're passing something by reference. Using ref with an extension method's 'this' parameter would violate that behavior.

编辑:我的观点是,方法调用应该要求您在通过引用传递内容时使用ref关键字。使用带有扩展方法的参数'this'参数会违反该行为。

#1


19  

You have to specify ref and out explicitly. How would you do this with an extension method? Moreover, would you really want to?

您必须明确指定ref和out。你会如何使用扩展方法执行此操作?而且,你真的想要吗?

TestClass x = new TestClass();
(ref x).ChangeWithExtensionMethod(otherTestClass);
// And now x has changed?

Or would you want to not have to specify the ref part, just for the first parameter in extension methods?

或者您是否希望不必指定ref部分,仅用于扩展方法中的第一个参数?

It just sounds weird to me, to be honest, and a recipe for unreadable (or at least hard-to-predict) code.

对我而言,这听起来很奇怪,说实话,以及不可读(或至少难以预测)代码的配方。

#2


5  

I agree with the answers from Jon Skeet et al. about how allowing "ref this" extension methods could make the code more obscure. But if you look at some namespaces in the .Net Framework, it is common for a method invoked on a struct to alter it.

我同意Jon Skeet等人的回答。关于如何允许“ref this”扩展方法可以使代码更加模糊。但是如果你看一下.Net Framework中的一些命名空间,在结构上调用的方法通常会改变它。

Take for example the System.Drawing structs (Point, Rectangle, etc). Each of these has methods (e.g. Offset, Inflate, etc) that mutate the struct itself. I'm not saying this is a good idea, in fact I personally find it very annoying that Offset, Inflate, etc mutate the structs themselves instead of returning new ones, and I know some of you are opposed to the idea of mutable structs in general.

以System.Drawing结构(Point,Rectangle等)为例。其中每一个都有改变结构本身的方法(例如Offset,Inflate等)。我不是说这是一个好主意,事实上我个人觉得Offset,Inflate等变异结构本身而不是返回新结构非常烦人,我知道你们中有些人反对可变结构的想法一般。

I doubt there are any cases where invoking a method of a reference type will change the reference (unless it's with the String class, where I can imagine there might be some compiler magic to switch references to perform interning, etc). So it makes sense to prevent "this ref" from being used with reference types, because changing a reference would be a completely non-standard side-effect of calling a method.

我怀疑在任何情况下调用引用类型的方法都会改变引用(除非它与String类有关,我可以想象可能会有一些编译器魔术来切换引用以执行实习等)。因此,防止“this ref”与引用类型一起使用是有意义的,因为更改引用将是调用方法的完全非标准的副作用。

But in regards to structs, allowing "this ref" would not significantly decrease code readability any more than Rectangle.Inflate, etc, and it would provide the only means to "simulate" that kind of behavior with an extension function.

但是对于结构体,允许“this ref”不会显着降低代码可读性,而不仅仅是Rectangle.Inflate等,它将提供使用扩展函数“模拟”这种行为的唯一方法。

Just as a side-note, here is one example where "this ref" might be useful, and IMHO still readable:

正如旁注,这里有一个例子,其中“这个参考”可能有用,恕我直言仍然可读:

void SwapWith<T>(this ref T x, ref T y) {
   T tmp = x; x = y; y = tmp;
}

#3


3  

I agree that it useful for struct

我同意它对struct很有用

So I want to propose that for making extension method for struct. this keyword should always pass struct by reference

所以我想建议为struct创建扩展方法。此关键字应始终通过引用传递struct

class always pass by reference anyway. And whenever we create extension method we want it to behave like a real method. So real method of class and struct can modified its value. Extension method should be able to too

无论如何,班总是通过引用传递。每当我们创建扩展方法时,我们希望它表现得像一个真正的方法。所以类和结构的真正方法可以修改它的值。扩展方法也应该能够

#4


1  

This would mean that calling myObject.ChangeWithExtentionMethod(otherObject) would actually have the potential to change myObject's value. IMO, that wouldn't make for very readable code when you can instead achieve the desired effect by using a regular non-extension method with a ref.

这意味着调用myObject.ChangeWithExtentionMethod(otherObject)实际上有可能改变myObject的值。 IMO,当你可以通过使用带有ref的常规非扩展方法来实现期望的效果时,这不会产生非常易读的代码。

EDIT: My point is, the method call should require you to use the ref keyword any time that you're passing something by reference. Using ref with an extension method's 'this' parameter would violate that behavior.

编辑:我的观点是,方法调用应该要求您在通过引用传递内容时使用ref关键字。使用带有扩展方法的参数'this'参数会违反该行为。