Zwracanie więcej niż jednego wyniku z metody – tuple

Czy zmierzyłeś się kiedyś z programem, w którym trzeba było zwrócić więcej niż jeden wynik z metody? Jest kilka sposobów, aby sobie z tym poradzić, a tuple może być tym, czego potrzebujesz.

Problem

Spójrzmy na kod, w którym analizujemy dane transakcji, aby pokazać je na ekranie. Mamy na to oddzielną metodę: GetTransactionData

string Data = "Michał;Breakfast;59;2021-02-13";

var value = new TupleExample().GetTransactionData(Data, out string customer);
Console.WriteLine($"Customer {customer} bought an item for {value}");

public class TupleExample
{
    public decimal GetTransactionData(string data, out string customer)
    {
        var chunks = data.Split(';');
        customer = chunks.First();

        return decimal.Parse(chunks[2]);
    }
}

 

A oto rezultat aplikacji konsolowej:

Możliwe rozwiązania

Możemy do tego problemu podejść na kilka sposobów. Najgorszy wydaje się ten, który zaproponowałem na początku, zwracając dodatkowe wyniki jako parametry wyjściowe. Niemniej jednak widziałem tę konstrukcję więcej niż raz i są przypadki, w których może być ona użyteczna. Na przykład:

var isSuccess = decimal.TryParse("59,95", out decimal result);

Innym podejściem będzie stworzenie nowej klasy, która zwróci rezultat jaki chcemy. Kod będzie wyglądał następująco:

var transactionData = new TupleExample().GetTransactionData(Data);
Console.WriteLine($"Customer {transactionData.Customer} bought an item for {transactionData.Value}");

public class TransactionData
{
    public string Customer { get; set; }
    public decimal Value { get; set; }
}

public class TupleExample
{
    public TransactionData GetTransactionData(string data)
    {
        var chunks = data.Split(';');

        return new TransactionData
        {
            Customer = chunks.First(),
            Value = decimal.Parse(chunks[2])
        };
    }
}

To rozwiązanie jest poprawne pod każdym względem. Stworzyliśmy klasę reprezentującą to, co zwracamy z metody. Właściwości mają prawidłowe nazwy.
A co by było, gdybyśmy mogli osiągnąć ten sam rezultat bez tworzenia nowej klasy?

Poznaj tuple

Tuple(krotka) to typ wartościowy, który może przechowywać zestaw danych. Jest to bardzo elastyczna struktura, podobna do typów dynamicznych, dzięki czemu możesz nadawać nazwy swoim właściwościom. Skończmy mówić i przejdźmy do kodu:

var transactionData = new TupleExample().GetTransactionData(Data);
Console.WriteLine($"Customer {transactionData.Customer} bought an item for {transactionData.Value}");

public class TupleExample
{
    public (string Customer, decimal Value) GetTransactionData(string data)
    {
        var chunks = data.Split(';');

        return (chunks.First(), decimal.Parse(chunks[2]));
    }
}

Czy zauważyłeś, że w ogóle nie zmieniłem kodu, który wywołuje metodę GetTransactionData? 😲 Jest to zmiana, która wpływa tylko na samą metodę, ale czyni ją prostszą i bardziej zwięzłą.

Zwróć uwagę, jak można zdefiniować tuple:

Możesz stworzyć tuple przy pomocy operatora new lub przy pomocy nawiasów.

var tuple = new Tuple<string, decimal>("John", 20);
(string, decimal) tuple2 = ("Anna", 30);
(string Name, decimal Value) tuple3 = ("Cathrine", 40);

Console.WriteLine($"Customer {tuple2.Item1} bought an item for {tuple2.Item2}");
Console.WriteLine($"Customer {tuple3.Name} bought an item for {tuple3.Value}");

Możesz określić nazwy właściwości jeśli chcesz, a jeżeli nie, to będą miały swoje domyślne nazwy: Item1, Item2, itd.

Podsumowanie

Tuple to prosty, dynamiczny typ, który świetnie nadaje się w momencie, gdy nie chcemy tworzyć klasy tylko do jednego użycia. Jest elastyczny i łatwy w tworzeniu.

Czy tuple sprawdzi się w Twoim kodzie? Ja zdecydowanie dam mu szanse 😀

 

 

One thought on “Zwracanie więcej niż jednego wyniku z metody – tuple

Leave a Reply

Your email address will not be published. Required fields are marked *