5

I need to create Tuple from list of datatype in string, but did not get any solution.

Here is example of what I want to do.

string[] dataType = {"int", "float", "datetime"};

//I want to create list like this but dynamically datatype come from db.
//List<Tuple<int, string, string>> list = new List<Tuple<int, string, string>>(); 

List<Tuple<dataType[0],dataType[1], dataType[2]>> list = new List<Tuple<dataType[0],dataType[1], dataType[2]>>();
//Here datatype value is in string so I want to convert string to actual datatype.

Or if any alternative solution for this please guide me.

9
  • You could use dynamic as the type Commented Apr 9, 2020 at 9:43
  • can please give me example of that. Commented Apr 9, 2020 at 9:47
  • Check Tuple.Create, This may solve your problem Commented Apr 9, 2020 at 10:14
  • You have ways to create List<Tuple<dataType[0],dataType[1], dataType[2]>>, but you can't use the created value as List<Tuple<dataType[0],dataType[1], dataType[2]>> in your code. Everything has to be runtime. What do you want to do with the list created? Commented Apr 9, 2020 at 10:19
  • Hi @PravinTukadiya, see the answer I posted. Commented Apr 9, 2020 at 10:21

2 Answers 2

1

This is to extend my comments under question, and show you what I meant there.

It is not hard to create a list of Tuple dynamically from list of types in string format. For example, use reflection:

private Type InferType(string typeName)
{
    switch (typeName.ToLowerInvariant())
    {
        case "int":
            return typeof(int);
        case "float":
            return typeof(float);
        default:
            return Type.GetType($"System.{typeName}", true, true);
    }
}

private object CreateListOfTupleFromTypes(string[] types)
{
    var elementTypes = types.Select(InferType).ToArray();

    // Get Tuple<,,>
    var tupleDef = typeof(Tuple)
        .GetMethods(BindingFlags.Static | BindingFlags.Public)
        .First(mi => mi.Name == "Create"
            && mi.GetParameters().Count() == elementTypes.Length)
        .ReturnType
        .GetGenericTypeDefinition();

    // Get Tuple<int, float, DateTime>
    var tupleType = tupleDef.MakeGenericType(elementTypes);

    // Get List<Tuple<int, float, DateTime>>
    var listType = typeof(List<>).MakeGenericType(tupleType);

    // Create list of tuple.
    var list = Activator.CreateInstance(listType);

    return list;
}

The problem is because the list is created using types only known at runtime, in your code, you can never use the list as strong typed list. i.e.List<Tuple<int, float, DateTime>>.

Of course, you could make life easier when the list is used in your code by using ITuple:

var list = new List<ITuple>();
list.Add(new Tuple<int, float, DateTime>(...);

int value1 = (int)list[0][0];
float value1 = (float)list[0][1];
DateTime value1 = (DateTime)list[0][2];

However, if you do that, then there is no point to use Tuple. You only need List<object[]>.

So, this comes back to my question, what is the list of tuple for in your code?

Sign up to request clarification or add additional context in comments.

Comments

-1

You could use dynamic here for your types. For example, when you read the three values from your database you could assign them without worrying about the types like so:

dynamic a = 10;
dynamic b = "Some String";
dynamic c = new DateTime(2020,4,9);

var test = new System.Tuple<dynamic,dynamic,dynamic>(a, b, c);

It would depend on what you want to do with the values later on.

To create a list of those tuples use:

var list = new List<System.Tuple<dynamic,dynamic,dynamic>>();

You can get the type of the variable, for instance a with

a.GetType().ToString();

I am not sure if you can set a variable type based on a string value, though (the second part of your question).

3 Comments

The OP is using System.Tuple not ValueTuple.
I don't think he is asking for dynamic, but rather want the tuple be of actual types.
@SinaHoseinkhani, the only way I can think of getting close to that is to write a factory method that returns a variable of that type. You could create a switch statement: switch (typeString): { case "string": return string a; case "int": return int a; .... }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.