Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#使用扩展方法更改值_C# - Fatal编程技术网

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
。我将删除几分钟前的评论,因为这可能会造成更多的混乱,而不是好处…很好的例子,我还没有意识到这一点。