neverlucky13
neverlucky13

Reputation: 79

multiple generic overloads

I have a simple helper class that I use to build a simple comma separated string.

private string AddcsvString(string s)
{
    if(string.IsNullOrWhiteSpace(this.Value))
    {
        return s;
    }
    else
    {
        return this.Value + "," + s;
    }
}

I also have a generic method that calls this

public void Add<T>(T s) where T: struct 
{
     this.Value = AddcsvString(s.ToString());
}

I wanted to add an overload for a generic List

public void Add<T>(IEnumerable<T> values)where T:struct 
{
    foreach (T t in values)
    {
        Add(t.ToString());
    }
}

But any attempt to call this called the first generic method. So I ended up renaming the second generic method to AddAll. In the end I think this was the right way to go for this case but would like to know if it is possible to have both for future reference.

--edit Here is the case that doesn't work

CsvString test = new CsvString();
string result;
test.Add(1);
test.Add('2');
test.Add("3");
result = test.ToString();  //  result = "1,2,3"

CsvString test2 = new CsvString();
List<long> aList = new List<long>();
string result2;
aList.Add(1);
aList.Add(2);
aList.Add(3);
test2.Add(aList);  //line doesn't compile

--edit 2 I found a second solution (though JoshE below gets credit for answering this, thanks btw). I changed the second method to this

public SWcsvString Add<T,K>(T values)where T: IEnumerable<K> where K: struct
{
    foreach (K k in values)
    {
        Add(k.ToString());
    }
    return this;
}

and the call to this

test2.Add<IEnumerable<long>,long>(aList);

Upvotes: 1

Views: 280

Answers (1)

Josh E
Josh E

Reputation: 7432

Try removing your constraints where T : struct, and I think you will get the proper behavior.

IEnumerable<char> <==> String, since a string is just a char[]. Since a string is not really a value-object, overload resolution will almost always favor the first method to avoid the boxing/unboxing operation of converting a string to IEnumerable<char>. (I'm guessing that you've tried calling it with both "foo" and IEnumerable<bar> where bar is a struct).

Upvotes: 1

Related Questions