gpt4 book ai didi

c# - 在 C# 中,为什么 dictionary[0]++ 有效?

转载 作者:IT王子 更新时间:2023-10-29 04:38:47 26 4
gpt4 key购买 nike

考虑以下 C# 代码:

var d = new Dictionary<int, int>();
d[0] = 0;
d[0]++;

这段代码执行后d[0]的值是多少?我期望 d[0] == 0,因为 Dictionary<> 的 Item 属性返回一个值类型 int,大概在堆栈上,然后递增。然而,令人惊讶的是,当您实际运行这段代码时,您会发现 d[0] == 1。

上面的示例表现得好像索引器正在返回引用类型,但现在考虑以下内容:

var d = new Dictionary<int, int>();
d[0] = 0;
var a = d[0];
a++;

这段代码执行后d[0]的值是多少?这次我们得到了预期的 d[0] == 0,因此索引器肯定没有返回引用。

有人知道为什么我们会看到这种行为吗?

最佳答案

C# 规范 7.6.9 Postfix increment and decrement operators :

The run-time processing of a postfix increment or decrement operation of the form x++ or x-- consists of the following steps:

  • if x is classified as a property or indexer access:
    • The instance expression (if x is not static) and the argument list (if x is an indexer access) associated with x are evaluated, and the results are used in the subsequent get and set accessor invocations.
    • The get accessor of x is invoked and the returned value is saved.
    • The selected operator is invoked with the saved value of x as its argument.
    • The set accessor of x is invoked with the value returned by the operator as its value argument.
    • The saved value of x becomes the result of the operation.

这实际上与值类型与引用类型语义无关,因为 --++ 不应该改变实例,而是返回具有新值的新实例.

public static class Test {
public static void Main() {
TestReferenceType();
TestValueType();
}
public static void TestReferenceType() {
var d=new Dictionary<int,BoxedInt>();
BoxedInt a=0;
d[0]=a;
d[0]++;
d[1]=2;
BoxedInt b=d[1];
b++;
Console.WriteLine("{0}:{1}:{2}:{3}",a,d[0],d[1],b);
}
public static void TestValueType() {
var d=new Dictionary<int,int>();
int a=0;
d[0]=a;
d[0]++;
d[1]=2;
int b=d[1];
b++;
Console.WriteLine("{0}:{1}:{2}:{3}",a,d[0],d[1],b);
}
public class BoxedInt {
public int Value;
public BoxedInt(int value) {
Value=value;
}
public override string ToString() {
return Value.ToString();
}
public static implicit operator BoxedInt(int value) {
return new BoxedInt(value);
}
public static BoxedInt operator++(BoxedInt value) {
return new BoxedInt(value.Value+1);
}
}
}

两种测试方法都将打印相同的字符串0:1:2:3。如您所见,即使使用引用类型,您也必须调用 set 访问器来观察字典中的更新值。

关于c# - 在 C# 中,为什么 dictionary[0]++ 有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28269825/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com