在C#程序中,我创建了一个从列表中删除对象的方法。用户输入要删除的项目的索引,然后要求用户确认删除,如果用户确认,则该项目将从列表中删除,否则列表保持不变。
我不确定将参数传递给方法的最佳方法。我尝试通过引用传递列表(作为out
参数):
static void DeleteCustomer(out List<Customer> customers)
{
// ...display list of objects for user to choose from...
int deleteId = ReadInt("Enter ID of customer to delete: ");
Console.Write("Are you sure you want to delete this customer?");
if (Console.ReadLine().ToLower() == "y")
{
customers.RemoveAt(deleteId);
}
}
以上代码无效,因为我收到错误使用未分配的本地变量&#39;客户&#39; 和 out参数&#39;客户&# 39;必须在控制离开当前方法之前指定。我以为我可以按值传递列表并返回相同的列表,如下所示:
static List<Customer> DeleteCustomer(List<Customer> customers)
{
int deleteId = ReadInt("Enter ID of customer to delete: ");
Console.Write("Are you sure you want to delete this customer?");
if (Console.ReadLine().ToLower() == "y")
{
customers.RemoveAt(deleteId);
}
return customers;
}
// ...which would be called from another method with:
List<Customer> customers = DeleteCustomer(customers);
但这似乎并不高效,因为相同的变量按值传递然后返回。
在这种情况下传递参数的最有效方法是什么?
答案 0 :(得分:4)
List
作为引用传递给对象,而不是它的副本。
请注意,这与通过引用引用非常不同,因为这意味着参数的赋值传播给调用者,而不是
这意味着对对象的修改(例如由RemoveAt
执行的修改)将自动传播给调用者。
因此,只需通过它;无需返回值或out
/ ref
参数。
您很少会将out
/ ref
用于参考类型,并且当用于值类型时,性能差异将会非常小而且不会让您担心,除非你已经分析并确定确定那里出现问题。使用最具惯用意义的东西。
答案 1 :(得分:2)
在C#中,参数按值传递。这意味着当您将参数传递给方法时,会传递参数的副本。 C#具有按值(如int)和引用(如任何类)的类型。 C#包含一个堆栈(当推送所有可变的时候)和一个堆。值类型的值直接在此堆栈中推送,而引用类型的引用在堆栈中推入,并且引用的值在堆中被推送。
传递引用类型(如List)时,它会复制引用,但此副本指向列表中的同一对象。因此,任何更改都会直接影响对象,除非您更改引用(使用assigmet),但这不是您的情况。
这可以通过您的代码:
static void DeleteCustomer<T>(List<T> customers)
{
Console.WriteLine("Enter ID of customer to delete: ");
int deleteId;
if (int.TryParse(Console.ReadLine(), out deleteId)) // if the input is an int
{
Console.Write("Are you sure you want to delete this customer?");
if (Console.ReadLine().ToLower() == "y")
{
customers.RemoveAt(deleteId);
}
}
else
{
Console.WriteLine("This is not valid Id");
}
}
如果您想了解ref an out关键字,我也可以帮助您,但是这个例子不是必需的。