New C# 7 features in action: Tuples in C# 7 – tuple types and tuple literals. Sample code for demonstrating the use of Dictionary with values of type Tuple

Tuples enhancements in C# 7

A. tuple types

Some example of the usage of tuple types:

Property of Tuple type

public (bool isValid, int errorCode, string errorMessage) OutputResult { get; set; }

Function with Tuple return type (bool isValid, int errorCode, string errorMessage)

private static (bool isValid, int errorCode, string errorMessage) HasValue(string inputString) // tuple return type - (bool isValid, int errorCode, string errorMessage)
{
     // Some Code
}

Dictionary with keys of type string and values of type Tuple

// result dictionary with keys of type string and values of type Tuple
var result = new Dictionary<string, (bool isValid, int errorCode, string errorMessage)>();

B. tuple literals

In below example, tuple literal (false, 3, "Input string only whitespaces")  is used to assign default value to property.

public (bool isValid, int errorCode, string errorMessage) OutputResult { get; set; } 
            =  (false, 3, "Input string only whitespaces");

In below example, tuple literal (isValid: success, errorCode: code, errorMessage: message)  is returned by the function.

private static (bool isValid, int errorCode, string errorMessage) HasValue(string inputString) // tuple return type - (bool isValid, int errorCode, string errorMessage)
{
	// Some Code
	return (isValid: success, errorCode: code, errorMessage: message); // tuple literal - (isValid: success, errorCode: code, errorMessage: message)
}

C. Accessing the tuple elements in a literal

In below example, HasValue function which returns (bool isValid, int errorCode, string errorMessage)  Tuple type is called and output (tuple value) is assigned to result. Then, tuple elements are accessed to form log message.

var result = HasValue(inputString);

if (result.isValid == false)
{
	string logMessage = $"{nameof(result.errorCode)}: {result.errorCode}, {nameof(result.errorMessage)}: {result.errorMessage}";
}

Another examples:

(bool isValid, int errorCode, string errorMessage) outputResult 
	= (false, 3, "Input string only whitespaces");

bool valid = outputResult.isValid;
int errorCode = outputResult.errorCode;
string errrorMessage = outputResult.errorMessage;

Full working sample code to demonstrate the C# 7’s Tuples enhancements – tuple types and tuple literals

Note the use of

tuple types –  (bool isValid, int errorCode, string errorMessage)
tuple literals –  (isValid: success, errorCode: code, errorMessage: message)
way of accessing the tuple elements in a literal (result) –  string logMessage = $"{nameof(result.errorCode)}: {result.errorCode}, {nameof(result.errorMessage)}: {result.errorMessage}";

in the below code.

Also, below code demonstrates the use of Dictionary with values of type Tuple.

    /// <summary>
    ///     CSharp7Sample.
    /// </summary>
    public partial class CSharp7Sample
    {
        /// <summary>
        ///     Checks Input Data is valid.
        /// </summary>
        /// <param name="inputData">Input data.</param>
        /// <returns>true or false.</returns>
        public static bool IsValidInputDataWithLogging(Dictionary<string, string> inputData)
        {
            var result = CSharp7Sample.HasValidValues(inputData);
            var invalidData = result.Where(x => x.Value.isValid == false);

            if (invalidData.Any() == false)
            {
                return true;
            }

            var logMessages = new StringBuilder();

            foreach (var item in invalidData)
            {
                var value = item.Value;
                logMessages.Append($"{nameof(item.Key)}: {item.Key}, {nameof(item.Value)}: {item.Value}, {nameof(value.errorCode)}: {value.errorCode}, {nameof(value.errorMessage)}: {value.errorMessage}"); // Access the elements of Tuple individually
                logMessages.AppendLine();
            }

            Console.Write(logMessages.ToString());

            return false;
        }

        /// <summary>
        ///     Checks Input String is valid.
        /// </summary>
        /// <param name="inputString">Input string.</param>
        /// <returns>true or false.</returns>
        public static bool IsValidInputStringWithLogging(string inputString)
        {
            var result = CSharp7Sample.HasValue(inputString);

            if (result.isValid == false)
            {
                string logMessage = $"{nameof(inputString)}: {inputString}, {nameof(result.errorCode)}: {result.errorCode}, {nameof(result.errorMessage)}: {result.errorMessage}"; // Access the elements of Tuple individually
                Console.Write(logMessage);
            }

            return result.isValid;
        }

        /// <summary>
        ///     Has Valid Values.
        /// </summary>
        /// <param name="inputData">Input Data.</param>
        /// <returns>Output Validation Result.</returns>
        private static Dictionary<string, (bool isValid, int errorCode, string errorMessage)> HasValidValues(Dictionary<string, string> inputData)
        {
            // result dictionary with keys of type string and values of type Tuple
            var result = new Dictionary<string, (bool isValid, int errorCode, string errorMessage)>(); // Dictionary with string keys and Tuple values 

            foreach (var inputString in inputData)
            {
                result.Add(inputString.Key, CSharp7Sample.HasValue(inputString.Value));
            }

            return result;
        }

        /// <summary>
        ///     Input string has value or not.
        /// </summary>
        /// <param name="inputString">Input string.</param>
        /// <returns>Tuple.</returns>
        private static (bool isValid, int errorCode, string errorMessage) HasValue(string inputString) // tuple return type - (bool isValid, int errorCode, string errorMessage)
        {
            int code = 0;
            string message = string.Empty;

            if (inputString == null)
            {
                code = 1;
                message = "Input string is null";
            }
            else if (inputString.Equals(string.Empty))
            {
                code = 2;
                message = "Input string is empty";
            }
            else if (inputString.Trim().Equals(string.Empty))
            {
                code = 3;
                message = "Input string only whitespaces";
            }

            bool success = string.IsNullOrEmpty(message);

            return (isValid: success, errorCode: code, errorMessage: message); // tuple literal - (isValid: success, errorCode: code, errorMessage: message)
        }
    }
}

Note: Tuples enhancements needs the ValueTuple types. Add “System.ValueTuple” NuGet package on frameworks that do not include these types.

Happy Coding !!!

You may also like...

Leave a Reply

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