Home > Software design >  Executing DateTime.Parse on a tuple in C#
Executing DateTime.Parse on a tuple in C#

Time:11-16

Is there a way to execute DateTime.Parse on a tuple in C#.

I am using Specflow and part of the tests I am executing involve testing a list of DateTime tuples (e.g. List<(DateTime, DateTime)>). In this step I am taking in a string, parsing it into a list of strings, where each string represents a DateTime pair separated by =.

The plan was to create a tuple store the value by splitting the string, creating a string tuple, then parsing that tuple using DateTime.Parse.

This doesn't work, giving me a CS1503 error (Argument n: cannot convert from 'type x' to 'type y'), and I cannot find any other information online about using DateTime.Parse on tuples. Is there another way of changing these values into DateTime?

Below is an extract of my code for reference:

public class TimeModeServiceStepDefinitions
{
    List<(DateTime, DateTime)> expectedResult = new List<(DateTime, DateTime)>();

    [Given(@"I have the following list of expected results: '([^']*)'")]
    public void GivenIHaveTheFollowingListOfExpectedResults(string p0)
    {
        List<string> tuples = p0.Split('|').ToList();
        foreach (var tuple in tuples)
        {
            var timeTuple = (first: "first", second: "second");
            timeTuple = tuple.Split('=') switch { var a => (a[0], a[1]) };
            expectedResult.Add(DateTime.Parse(timeTuple));
        }
    }
}

CodePudding user response:

DateTime.Parse accepts a string supposed to contain one date/time. So, we can simply write:

string[] a = tupleString.Split('=');
var timeTuple = (first: DateTime.Parse(a[0]), second: DateTime.Parse(a[1]));

where timeTuple is of type (DateTime first, DateTime second).

var timeTuple = (first: "first", second: "second"); is a strange way of declaring a tuple variable. C# does not only have a tuple syntax for tuple values but also for tuple types:

(DateTime first, DateTime second) namedTuple;
(DateTime, DateTime) unnamedTuple; // With elements named Item1, Item2

CodePudding user response:

Ideally, you'd just map DateTime.Parse over a tuple, but I don't think there is a way to do so as part of standard library. You can easily write an extension that would help you write such code (Select is essentially the name chosen for map operation in LINQ):

static class TupleExtensions
{
    public static (TResult,TResult) Select<T,TResult>(
        this (T,T) v, Func<T,TResult> f)
          => (f(v.Item1), f(v.Item2));
}

And then you can write:

    string p0 = "2022-11-11=2022-12-12";
    List<string> tuples = p0.Split('|').ToList();
    var expectedResult = 
         tuples.Select(tuple => tuple.Split('=') switch { var a => (a[0], a[1]) })
         .Select(x => x.Select(DateTime.Parse))
         .ToList();
  • Related