2

I have a method to concatenate strings provided by int?.

public string ConcatenateNumber(IEnumerable<int?> myList)
{
    return myList
        .Distinct()
        .Aggregate(
            new StringBuilder(), 
            (current, next) => current.Append("'").Append(next))
        .ToString()
        .Substring(1);
}

Now I want to do unit test.

[TestMethod]
public void InputIntegers_Should_Be_Concatenated_When_Consider_Distinct()
{
    var myList = CreateEnumerable(1, 2, 2, 3);
    var logic = new MainLogic();
    var result = logic.ConcatenateNumber(myList);
    Assert.AreEqual("1'2'3", result);
}

public IEnumerable<T> CreateEnumerable<T>(params T[] items)
{
    if (items == null)
        yield break;

    foreach (T mitem in items)
        yield return mitem;
}

However I have the compile error.

C#: Unknown method ConcatenateNumber(System.Collections.Generic.IEnumerable) of ....

I think it is caused by nullable integer int?. But I am not sure how to fix it.

Shaun Luttin
  • 107,550
  • 65
  • 332
  • 414
Bigeyes
  • 1,146
  • 2
  • 15
  • 33

2 Answers2

2

Explicitly pass the type as a nullable int.

var myList = CreateEnumerable<int?>(1, 2, 2, 3);

For example:

using System;
using System.Linq;              
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        var p = new Program();

        var list = p.CreateEnumerable<int?>(1, 2, 3, 4);
        p.DoWork(list);         
    }

    public void DoWork(IEnumerable<int?> enumerable)
    {
        enumerable.ToList().ForEach(x => 
        {
            Console.WriteLine(x);
        });
    }

    public IEnumerable<T> CreateEnumerable<T>(params T[] items)
    {
        if (items == null)
            yield break;

        foreach (T mitem in items)
            yield return mitem;
    }
}
Shaun Luttin
  • 107,550
  • 65
  • 332
  • 414
  • Do not use `.ToList()` just to call `.ForEach(...)` ... this causes the set to be looped twice is provides no benefits. – Matthew Whited Feb 15 '17 at 17:16
  • @MatthewWhited `ForEach` does not exist on `IEnumerable`. – Shaun Luttin Feb 15 '17 at 17:17
  • @MatthewWhited `foreach` and `ToList().ForEach()` appear to make the same number of loops: https://dotnetfiddle.net/V7iExb – Shaun Luttin Feb 15 '17 at 17:29
  • 2
    Only because you're only counting half of the loops in that fiddle, you aren't counting the loops internal to `ToList()`. It's also wasting memory as well as time. – Jon Hanna Feb 15 '17 at 17:50
  • That's because your code is wrong. In the second set you are incrementing the set twice for each `.MoveNext()`. In the first you are counting the values twice in succession. – Matthew Whited Feb 15 '17 at 17:53
  • check out what really happens with your code here... you will see why I said it is passed twice. https://dotnetfiddle.net/mC31k5 – Matthew Whited Feb 15 '17 at 18:01
  • 1
    No problem ... I see people do this all the time and they just don't get why I try to tell them to do it differently :) – Matthew Whited Feb 15 '17 at 18:07
2
public void InputIntegers_Should_Be_Concatenated_When_Consider_Distinct()
{
    var myList = CreateEnumerable(1, 2, 2, 3);
    var logic = new MainLogic();
    var result = logic.ConcatenateNumber(myList);
}

public IEnumerable<T> CreateEnumerable<T>(params T[] items)
{
    return items ?? Enumerable.Empty<T>();
}

public class MainLogic
{

    public string ConcatenateNumber<T>(IEnumerable<T> myList)
    {
        // do this if you want to remove nulls
        return string.Join("'", myList.Where(i => i != null).Distinct()); 

        //return string.Join("'", myList.Distinct()); // otherwise do this
    }
}
Matthew Whited
  • 21,248
  • 2
  • 48
  • 67