irl_steve
irl_steve

Reputation: 13

Executing DateTime.Parse on a tuple in C#

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));
        }
    }
}

Upvotes: 0

Views: 212

Answers (2)

Olivier Jacot-Descombes
Olivier Jacot-Descombes

Reputation: 112632

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

Upvotes: 2

Alexei Levenkov
Alexei Levenkov

Reputation: 100555

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();

Upvotes: -1

Related Questions