5

Is it possible to write a C# method that accepts a value tuple with any number of items of the same type and converts them into a list?

Edit 2/6/2019 I accepted the Provided answer as the correct one. I wanted to also provide a solution that uses a base class that is not an interface, becuase I am trying to write a conversion operator and user defined conversions from an interface are not allowed.

public static class TupleExtensions
{
    public static IEnumerable<object> Enumerate(this ValueType tpl)
    {
        var ivt = tpl as ITuple;
        if (ivt == null) yield break;

        for (int i = 0; i < ivt.Length; i++)
        {
            yield return ivt[i];
        }
    }
}
Kobi Hari
  • 1,259
  • 1
  • 10
  • 25

1 Answers1

7

You can use the fact that ValueTuples implement the ITuple interface.

The only issue is that tuple elements can be of arbitrary type, so the list must accept any kind of type.

public List<object> TupleToList(ITuple tuple)
{
  var result = new List<object>(tuple.Length);
  for (int i = 0; i < tuple.Length; i++)
  {
    result.Add(tuple[i]);
  }
  return result;
}

This also works as an extension method:

public static class ValueTupleExtensions
{
  public static List<object> ToList(this ITuple tuple)
  {
    var result = new List<object>(tuple.Length);
    for (int i = 0; i < tuple.Length; i++)
    {
      result.Add(tuple[i]);
    }
    return result;
  }
}

This way it is possible to write var list = (123, "Text").ToList();.

Edit 2020-06-18: If every element of the tuple is of the same type it's possible to create list with the proper element type:

public List<T> TupleToList<T>(ITuple tuple)
{
  var result = new List<T>(tuple.Length);
  for (int i = 0; i < tuple.Length; i++)
  {
    result.Add((T)tuple[i]);
  }
  return result;
}
ckuri
  • 3,784
  • 2
  • 15
  • 17
  • Oh, I didn't know they added that interface, I remember wanting something like that with the regular tuples. Good to know. – Jeff Mercado Jun 02 '19 at 09:05
  • @JeffMercado As there is a [ToValueTuple](https://learn.microsoft.com/en-us/dotnet/api/system.tupleextensions.tovaluetuple?view=netframework-4.8) extension method you could convert a Tuple to a ValueTuple and then leverage the ITuple interface. – ckuri Jun 02 '19 at 09:08
  • Oh I know, I was just saying that before `ValueTuple` was a thing, the regular `Tuple` types didn't have a common interface which made trying to build things that operated on tuples unnecessarily difficult. – Jeff Mercado Jun 02 '19 at 09:10
  • VS can't seem to find the type `ITuple`. I am using .NET Core 2.0, and `using System.Runtime.CompilerServices`. I also have `System.ValueTuple` referenced. Do I need anything else? – Sweeper Jun 02 '19 at 09:12
  • @Sweeper, I just set up a quick netcore app and dumped the interfaces on the valuetuple type and it includes `ITuple` so it doesn't seem like it needs anything else. Are you running a stable version by any chance? I have 2.2.100 currently. – Jeff Mercado Jun 02 '19 at 09:17
  • I am running on exactly 2.0.0, at least that's what `dotnet --info` told me. @JeffMercado Maybe that's the reason. – Sweeper Jun 02 '19 at 09:20
  • That's a great answer, and It is actually correct. The problem is that I am trying to use it in user defined conversion (casting operator) and it refuses to accept an interface. Is there anything similar with a class? (perhaps a common base class) – Kobi Hari Jun 02 '19 at 10:28
  • There is no base class for ValueTuples. I don’t know what you mean with "refuses to accept an interface". Extension methods like in your edited question (and as shown in my appended answer) or operator overloads do accept interfaces. – ckuri Jun 02 '19 at 11:17
  • The question was "a value tuple with any number of items **of the same type**". – AgentFire Jun 18 '20 at 06:43
  • @AgentFire I edited my answer regarding your input. – ckuri Jun 18 '20 at 17:40