Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I/O Cascading in c#

Tags:

c#

io

In C++,'>>' and '<<' are used for cascading during performing the Input/Output Operations.
Is there any way in which such things can be done in C#? Till now, I know that I can take one input at a time and assign it to a variable, for eg, in the following code snippet :

int a,b;
Console.Write("Enter the value of first number: ");
a=Convert.ToInt32(Console.ReadLine());
Console.Write("Enter the value of second number: ");
b=Convert.ToInt32(Console.ReadLine());

whereas in C++, the same thing can be done as:

int a,b;
cout<<"Enter the values of the two numbers: ";
cin>>a>>b;
like image 492
Rajdeep Dutta Avatar asked Oct 16 '22 17:10

Rajdeep Dutta


1 Answers

As @fredrik and @Henk Holterman said this feature is not built in into the language. BUT... (big but here) we are programmers!! and there is very little we are not able to implement by ourselves!

Before explaining let's take a look to the code, as many times the code can explain itself:

public class Reader
{
    public Reader Read<T>(out T t) where T : struct
    {
        var line = Console.ReadLine();
        t = GetValueFromStringRepresentation<T>(line);
        return this;
    }

    public Reader Read(out string str)
    {
        str = Console.ReadLine();
        return this;
    }

    //GetValueFromStringRepresentation stuff
}

We implement a method chain pattern here to keep reading as many times as needed, and we use out parameters to initialize our variables. This implementation works only for structs (but not all...) and for string, that is the reason for the overloaded method that takes a string... C# does not allow to specify AND in type parameter constraints... =(

The next thing is to parse a string value, here is how I did it... be nice.. it is just democode:

private static T GetValueFromStringRepresentation<T>(string str)
{
    var type = typeof(T);
    var value = type == typeof(string)
        ? str
        : type == typeof(bool)
            ? bool.Parse(str)
            : type == typeof(sbyte)
                ? sbyte.Parse(str, CultureInfo.InvariantCulture)
                : type == typeof(byte)
                    ? byte.Parse(str, CultureInfo.InvariantCulture)
                    : type == typeof(short)
                        ? short.Parse(str, CultureInfo.InvariantCulture)
                        : type == typeof(ushort)
                            ? ushort.Parse(str, CultureInfo.InvariantCulture)
                            : type == typeof(int)
                                ? int.Parse(str, CultureInfo.InvariantCulture)
                                : type == typeof(uint)
                                    ? uint.Parse(str, CultureInfo.InvariantCulture)
                                    : type == typeof(long)
                                        ? long.Parse(str, CultureInfo.InvariantCulture)
                                        : type == typeof(char)
                                            ? char.Parse(str)
                                            : type == typeof(float)
                                                ? float.Parse(str, CultureInfo.InvariantCulture)
                                                : type == typeof(double)
                                                    ? double.Parse(str, CultureInfo.InvariantCulture)
                                                    : type == typeof(ulong)
                                                        ? ulong.Parse(str, CultureInfo.InvariantCulture)
                                                        : type == typeof(decimal)
                                                            ? decimal
                                                                .Parse(str, CultureInfo.InvariantCulture)
                                                            : type == typeof(Guid)
                                                                ? Guid.Parse(str)
                                                                : (object)null;
    return (T)value;
}

As I said before this will not work out of the box for every possible struct, but you can add easily an optional parameter that encapsulates the parsing, something like: Func< string, T > parser.

And testing:

    int a, b;
    string c;
    char d;

    var reader = new Reader();
    reader.Read(out a)
        .Read(out b)
        .Read(out c)
        .Read(out d);

    Console.WriteLine(a);
    Console.WriteLine(b);
    Console.WriteLine(c);
    Console.WriteLine(d);
    Console.ReadLine();

EDIT

If you are using C# 7+, you can take advantage of inline varaible declaration:

    var reader = new Reader();
    reader.Read(out int a)
        .Read(out int b)
        .Read(out string c)
        .Read(out char d);
like image 157
taquion Avatar answered Oct 20 '22 15:10

taquion