我想详细说明埃里克·利珀特(Eric Lippert)在回答中提出的具体观点,并把焦点放在任何其他人都没有触及的特定场合。埃里克(Eric)说:
[...]分配几乎总是留下刚在寄存器中分配的值。
我想说的是,赋值将始终留下我们尝试分配给左操作数的值。不只是“几乎总是”。但是我不知道,因为我没有在文档中发现此问题。从理论上讲,“离开”而不重新评估左操作数可能是一个非常有效的实现过程,但是有效吗?
到目前为止,针对此线程答案构建的所有示例均“有效”。但是对于使用get和set访问器的属性和索引器而言,效率很高吗?一点也不。考虑以下代码:
class Test
{
public bool MyProperty { get { return true; } set { ; } }
}
这里有一个属性,它甚至不是私有变量的包装。每当有人要求他返回真相时,每当有人试图设定自己的价值时,他就什么都不做。因此,每当评估此属性时,他就应该诚实。让我们看看发生了什么:
Test test = new Test();
if ((test.MyProperty = false) == true)
Console.WriteLine("Please print this text.");
else
Console.WriteLine("Unexpected!!");
猜猜它打印了什么?它打印Unexpected!!
。事实证明,确实调用了set访问器,它什么也不做。但是此后,根本不会调用get访问器。分配只是留下了false
我们尝试分配给属性的值。而此false
值是if语句求值的值。
我将以一个使我研究这个问题的真实示例作为结尾。我创建了一个索引器,该索引器是我List<string>
的类作为私有变量的集合()的便捷包装。
发送到索引器的参数是一个字符串,该字符串将被视为我的集合中的值。如果该值存在于列表中,则get访问器将仅返回true或false。因此,get访问器是使用该List<T>.Contains
方法的另一种方法。
如果以字符串作为参数调用了索引器的set访问器,而正确的操作数是bool true
,则他会将该参数添加到列表中。但是,如果将相同的参数发送给访问器,并且正确的操作数是bool false
,他将改为从列表中删除该元素。因此set访问被用作方便的替代都List<T>.Add
和List<T>.Remove
。
我以为我有一个简洁紧凑的“ API”,其中包含我自己的逻辑(作为网关)来包装列表。仅依靠索引器的帮助,我就可以通过几次击键来完成很多事情。例如,如何尝试将值添加到列表中并验证其是否在其中?我认为这是唯一需要的代码行:
if (myObject["stringValue"] = true)
; // Set operation succeeded..!
但是,正如我之前的示例所示,甚至没有调用应该查看该值是否确实在列表中的get访问器。该true
值始终被有效地破坏了我在get访问器中实现的任何逻辑。