【发布时间】:2018-06-13 00:43:15
【问题描述】:
public class PropertyManager
{
private Dictionary<ElementPropertyKey, string> _values = new Dictionary<ElementPropertyKey, string>();
private string[] _values2 = new string[1];
private List<string> _values3 = new List<string>();
public PropertyManager()
{
_values[new ElementPropertyKey(5, 10, "Property1")] = "Value1";
_values2[0] = "Value2";
_values3.Add("Value3");
}
public ref string GetPropertyValue(ElementPropertyKey key)
{
return ref _values[key]; //Does not compile. Error: An expression cannot be used in this context because it may not be returned by reference.
}
public ref string GetPropertyValue2(ElementPropertyKey key)
{
return ref _values2[0]; //Compiles
}
public ref string GetPropertyValue3(ElementPropertyKey key)
{
return ref _values3[0]; //Does not compile. Error: An expression cannot be used in this context because it may not be returned by reference.
}
}
在上面的示例中,GetPropertyValue2 编译,但 GetPropertyValue 和 GetPropertyValue3 不编译。 从字典或列表返回一个值作为参考有什么问题,而它确实适用于数组?
【问题讨论】:
-
在 7.2 中为值类型引入了引用语义。在返回引用类型的情况下,为什么需要
ref? -
@MichaWiedenmann,虽然您是正确的,但您的评论肯定与问题正交?在 OP 的示例代码中将
string更改为int仍然会产生相同的错误。 -
@Lander 你应该问为什么当你不能将它与其他容器一起使用时你可以将它与数组一起使用。 Jon Skeet answered 今天早些时候。
-
@Lander 索引器在具有值类型的容器上返回一个在堆栈中分配的值的副本,一旦您退出该方法,它将消失。你不能用
return ref安全地返回它。数组索引器由 CLR 本身提供,并返回对值 as shown in this answer 的引用 -
@DavidArno 在我链接到的第二个问题Indexers in List vs Arrays 中进行了解释。列表/字典索引器返回堆栈分配的副本,因此不安全。数组索引器是由 CLR 本身实现的特殊野兽,它返回对数据本身的引用,而不是数据的副本。重要的是这些引用延长了数组的生命周期,就好像它们是字段一样