C#使用扩展方法更改值
如果我有以下扩展方法:C#使用扩展方法更改值,c#,C#,如果我有以下扩展方法: internal static class Extensions { public static void Increase(this uint value) { value += 1; } public static void Decrease(this uint value) { if (value > 0) value -= 1; } } 为什么这不会导致将i更改为1 uint
internal static class Extensions
{
public static void Increase(this uint value)
{
value += 1;
}
public static void Decrease(this uint value)
{
if (value > 0) value -= 1;
}
}
为什么这不会导致将i
更改为1
uint i = 0;
i.Increase();
参数是按值传递的,仅此而已。在这方面,扩展方法没有什么特别之处。这相当于:
Extensions.Increase(i);
您需要该方法通过引用传递第一个参数(使用ref
),以使其生效。。。无论如何,扩展方法都禁止这样做
因此,虽然您可以编写一个方法,允许您将其称为:
Extensions.Increase(ref i);
您将无法将其作为扩展方法
另一种方法是使方法返回一个值,此时您可以:
i = i.Increase();
如果您不完全清楚“按引用传递”与“按值传递”语义,您可能需要阅读my。值类型是按值传递给方法的,您正在对该值的副本进行操作。请记住,编译器将
i.foo()
更改为StaticClass.foo(i)
,这只是语法上的糖分。@csharpfolk:默认情况下,所有内容都是按值传递的。整数是值类型-您在递增整数的副本,而不是实际的整数。您需要将整数传递为ref int
,以实现您的尝试,但是扩展方法不允许ref
。没有理由进行否决表决。你的问题在我看来是明确而合理的。(这可能是一个重复的问题,但这不是投反对票的好理由。)@MatthewWatson谢谢你。我只是想公开提问,看看我是否有什么需要改进的地方,还有我的问题……“扩展方法在这方面没有什么特别之处。”——除了值类型之外,实例方法的隐式this
参数确实被ref
传递,因此,即使扩展方法旨在模拟实例方法的语法,它们也无法实现相同的功能。@hvd可变结构值得怀疑。。。因此,我认为扩展方法达到了可比的“功能性”水平,导致了问题/疯狂的错误消息——只是在稍微不同的情况下:)@JonSkeet,我的观点是它们没有。这就是扩展方法的特殊之处:当t
是一个值类型时,通常在t.Method()
中,t
通过ref
。只有扩展方法才不会。但我当然同意Alexei的评论,即变异实例方法通常不是一个好主意,因此可能只有几个原因可以解释为什么需要变异扩展方法。我过去也曾写过这方面的文章。:)@哦,我明白你的意思了。。。虽然我不会用这种方式表达它,而且如果t
是一个只读变量,那么首先会获取一个副本,因此它实际上不是通过引用传递的t
。我将删除几分钟前的评论,因为这可能会造成更多的混乱,而不是好处…很好的例子,我还没有意识到这一点。