Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Errors when trying to add ref to an overloaded method's parameter [duplicate]

Tags:

c#

Why do I get the following to errors when I try to add ref to an overloaded method's parameter?

The best overloaded method match for 'WindowsFormsApplication1.Form1.SearchProducts(int)' has some invalid arguments

Argument 1: cannot convert from 'ref System.Collections.Generic.List' to 'int'

Here's some (simplified) code:

public virtual IList<int> SearchProducts(int categoryId)
{
    List<int> categoryIds = new List<int>();
    if (categoryId > 0)
        categoryIds.Add(categoryId);
    return SearchProducts(ref categoryIds);
}

public virtual IList<int> SearchProducts(ref IList<int> categoryIds)
{
    return new List<int>();
}

Edit:

Some of you asked me why I need ref in this case and the answer is that I probably don't need it, because I can clear the list and add new elements (I don't need to create a new reference). But the question is not about the fact that I need or don't need ref, it's about why I got the errors. And since I didn't find an answer (after googling for little while) I thought the question was interesting and worth asking here. It seems that some of you don't think it's a good question and voted to close it down ...

like image 734
david.s Avatar asked Mar 16 '26 00:03

david.s


2 Answers

When you pass an argument by reference, the compile-time type has to be the exact same type as the parameter type.

Suppose the second method was written as:

public virtual IList<int> SearchProducts(ref IList<int> categoryIds)
{
    categoryIds = new int[10];
    return null;
}

That must compile, as int[] implements IList<int>. However, it would break type safety if the caller actually had a variable of type List<int>, which now had a reference to an int[]...

You can fix this by making the declared type of categoryIds in the calling method IList<int> instead of List<int> - but I strongly suspect you don't actually want to pass the argument by reference in the first place. It's relatively rare to need to do so. How comfortable are you with C# parameter passing?

like image 187
Jon Skeet Avatar answered Mar 18 '26 13:03

Jon Skeet


Try the following:

public virtual IList<int> SearchProducts(int categoryId)
{
    IList<int> categoryIds = new List<int>();
    if (categoryId > 0)
    categoryIds.Add(categoryId);
    return SearchProducts(ref categoryIds);
}
like image 44
mreyeros Avatar answered Mar 18 '26 12:03

mreyeros



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!