mercredi 22 novembre 2017

C# runtime introspection on Tuple

In my C# application, I need to display a Tuple to users. The problem is that the Tuple could be of any form, and I don't know at compile time what the Tuple will look like, so I have to introspect on it at runtime to display it. The first problem is to identify the type of each component in the tuple, and the second is to get the value of each component.

Getting the value of each component seems to involve Item1, Item2, and so on, but is there a way to get at Items by index? Currently my code is really clunky because I have to use the number of components to decide how may items to iterate through (see below). The bigger problem is however, how to get at the elements because I don't know how to get the Tuple object. The following code compiles, but at runtime the cast of the object to Tuple throws an error of this form:

Unable to cast object of type 'System.Tuple2[System.String,System.Byte[]]' to type 'System.Tuple2[System.Object,System.Object]'.

It looks like the cast fails (I think I understand why), but I don't know how to rewrite the cast to get around this. I have tried things like:

object rowObject = ((Tuple<tupleTypeArray[0], tupleTypeArray[1]>)object).Item1;

but this does not compile. Help would be appreciated!

object = SomeTupleGotFromMethodCall();
Type tupleType = object.GetType();
Type[] tupleTypeArray = tupleType.GenericTypeArguments;
int tupleLength = tupleType.GenericTypeArguments.Count<Type>();
for (int i = 0; i < tupleLength; i++)
{
    if (tupleLength == 1)
    {
        if (i == 0)
        {
            Type firstType = tupleTypeArray[0];
            object rowObject = ((Tuple<object>)object).Item1;
            if (rowObject != null)
            {
                display(rowObject);
            }
        }
    }

    if (tupleLength == 2)
    {
        if (i == 0)
        {
            object rowObject = ((Tuple<object, object>)object).Item1;
            if (rowObject != null)
            {
                display(rowObject);
            }
        }

        if (i == 1)
        {
            object rowObject = ((Tuple<object, object>)object).Item2;
            display(rowObject);
        }
    }

    ...
}





Aucun commentaire:

Enregistrer un commentaire