List<T> 或 Collections 的编码风格 "ref"
Coding style "ref" for List<T> or Collections
我有一个函数可以改变列表类型的参数(改变内部对象状态)。例如:
public void ChangeList<T>(List<T> source, T value)
{
//Actions
source.Add(value);
//Actions
}
什么函数签名比较好?为什么?
第一个:public void ChangeList<T>(List<T> source, T value)
或
第二个:public void ChangeList<T>(ref List<T> source, T value)
编辑:问题可以修改。如何显式指定函数改变列表的状态? (函数名称或 ReadonlyCollection 除外)
第一个。第二个尖叫"I don't know what ref
means";这是完全错误的。这甚至不是风格问题,真的。在此上下文中使用 ref
的唯一原因是 ChangeList
方法是否需要 重新分配列表 (返回不同的列表实例,而不是执行名称建议,并改变现有列表)。在那种情况下,我认为 return
会更好:
public List<T> TransformBasedOnList<T>(List<T> source, T value) { ... }
只有在更改列表的引用时才应使用 ref:
例如
public void ChangeList<T>(ref List<T> source, T value)
{
//Actions
source = new List<T>; // or initialize using API/DB call
source.Add(value);
//Actions
}
扩展我的评论,请参阅此示例应用程序,它展示了通过 ref
:
传递参数之间的区别
static void Main(string[] args)
{
int val = 1;
int val2 = 1;
Add(ref val);
Add(val2);
Console.WriteLine("Add 44 to Refence of val: " + val);
Console.WriteLine("Add 44 to i, not by ref: " + val2);
Console.ReadKey();
}
static void Add(ref int i)
{
i += 44;
}
static void Add(int i)
{
i += 44;
}
输出:
如您所见,当通过 ref
传递值时,您更改了被调用方法范围的值 "outside"。调用方法知道这些更改。基本上,被调用的方法 "has a reference to that variable's memory location" 和那个位置都有一个赋值。我的控制台输出中确实有一个 type-o,应该是 Add 44 to val2, not by ref:
当您不使用ref
时,更改不会"recognized"超出被调用方法的范围。相反,它传递了参数/参数的 value,忽略了实际的内存引用,仅更改了方法的本地值。
不是一个很好的解释,说实话我的词汇量在这件事上并不出色(如果有人能纠正我,我会很高兴!)但我认为这个例子很简单,屏幕截图清楚地显示了差异.
编辑:另外,只需重新链接 MSDN:
https://msdn.microsoft.com/en-us/library/14akc2c7.aspx
并指出这一重要说明,
Do not confuse the concept of passing by reference with the concept of reference types. The two concepts are not the same. A method parameter can be modified by ref regardless of whether it is a value type or a reference type. There is no boxing of a value type when it is passed by reference.
A "reference type" 基本上只是一种仅引用内存位置的类型,因此您可以有 2 个引用相同对象实例的引用类型。 "value type" 直接包含实际值,您不能通过修改不同的值类型来弄乱一个值类型的值;它们是两个不同的实例,恰好具有相同的值。但是,使用 ref
,您可以使值类型的行为类似于引用类型。
可以把它想象成 "Get the coat on the third hook"- 这是一个参考。你知道外套在哪里,这是参考。如果你说,"Get my coat" 你就知道你得到的外套(价值)是多少。
我有一个函数可以改变列表类型的参数(改变内部对象状态)。例如:
public void ChangeList<T>(List<T> source, T value)
{
//Actions
source.Add(value);
//Actions
}
什么函数签名比较好?为什么?
第一个:public void ChangeList<T>(List<T> source, T value)
或
第二个:public void ChangeList<T>(ref List<T> source, T value)
编辑:问题可以修改。如何显式指定函数改变列表的状态? (函数名称或 ReadonlyCollection 除外)
第一个。第二个尖叫"I don't know what ref
means";这是完全错误的。这甚至不是风格问题,真的。在此上下文中使用 ref
的唯一原因是 ChangeList
方法是否需要 重新分配列表 (返回不同的列表实例,而不是执行名称建议,并改变现有列表)。在那种情况下,我认为 return
会更好:
public List<T> TransformBasedOnList<T>(List<T> source, T value) { ... }
只有在更改列表的引用时才应使用 ref: 例如
public void ChangeList<T>(ref List<T> source, T value)
{
//Actions
source = new List<T>; // or initialize using API/DB call
source.Add(value);
//Actions
}
扩展我的评论,请参阅此示例应用程序,它展示了通过 ref
:
static void Main(string[] args)
{
int val = 1;
int val2 = 1;
Add(ref val);
Add(val2);
Console.WriteLine("Add 44 to Refence of val: " + val);
Console.WriteLine("Add 44 to i, not by ref: " + val2);
Console.ReadKey();
}
static void Add(ref int i)
{
i += 44;
}
static void Add(int i)
{
i += 44;
}
输出:
如您所见,当通过 ref
传递值时,您更改了被调用方法范围的值 "outside"。调用方法知道这些更改。基本上,被调用的方法 "has a reference to that variable's memory location" 和那个位置都有一个赋值。我的控制台输出中确实有一个 type-o,应该是 Add 44 to val2, not by ref:
当您不使用ref
时,更改不会"recognized"超出被调用方法的范围。相反,它传递了参数/参数的 value,忽略了实际的内存引用,仅更改了方法的本地值。
不是一个很好的解释,说实话我的词汇量在这件事上并不出色(如果有人能纠正我,我会很高兴!)但我认为这个例子很简单,屏幕截图清楚地显示了差异.
编辑:另外,只需重新链接 MSDN:
https://msdn.microsoft.com/en-us/library/14akc2c7.aspx
并指出这一重要说明,
Do not confuse the concept of passing by reference with the concept of reference types. The two concepts are not the same. A method parameter can be modified by ref regardless of whether it is a value type or a reference type. There is no boxing of a value type when it is passed by reference.
A "reference type" 基本上只是一种仅引用内存位置的类型,因此您可以有 2 个引用相同对象实例的引用类型。 "value type" 直接包含实际值,您不能通过修改不同的值类型来弄乱一个值类型的值;它们是两个不同的实例,恰好具有相同的值。但是,使用 ref
,您可以使值类型的行为类似于引用类型。
可以把它想象成 "Get the coat on the third hook"- 这是一个参考。你知道外套在哪里,这是参考。如果你说,"Get my coat" 你就知道你得到的外套(价值)是多少。