I have a method that takes an object as an argument. The method needs to identify the type of object. This is easily accomplished for simple types like String and Double[], etc. I simply access the myObject.GetType().Name property.

But for generics like List<String[]>, etc. the Name property is always "List`1". I have to access the FullName property. This is cumbersome. Is their a better way?

Recommended Answers

All 8 Replies

For generic types you can test the IsGenericType property.
Then you need to use GetGenericArguments() to get an array of the types passed as arguments.
Just curious, but what are you doing that needs such analysis of types?
It is unusual to need to do such low level type reflection in normal apps.

I built a circuit that amplifies thermal noise from a transistor pair and feeds the output to a 16 bit ADC. I have a usb dio interface that collects the data in two bytes. The application crunches the raw bytes into various arrays of processed output (short[], double[], integer[], and char[])). Overall, its a truly random number generator.

This windows form application that presents datagridviews displaying the results. I now have a single PopulateGrid() method that converts any array or list of arrays to data rows/columns in string format.

Thanks for your great idea. I'm gonna use it.

Have you though of writing your code using generics.
That way you would not need to do any type checking as it would be managed by the compiler.

Well, I do use generics. I have a method:

public static void getGrid(System.Windows.Forms.DataGridView dg, object values, object columnHeaders)
      {
         //DO Stuff here that will convert any set of values or headers to a List<string[]> then create a data table;


      }

In my application I have several data types, some of which are generic lists. So far, the method handles byte[], double[], string[], int[], List<double[]>, List<string[]>, List<[int]>, List<char[]>, List<byte[]>.

I use these datagridviews frequently to display data of various types. Clearly, I could write several getGrid methods using specific types but I want to avoid the multiple overload approach. Am I right in my assumption that the only way to do this is to pass the argument as object.

No. You can write your own generic methods that are strongly typed but support many types.
Here is a little example.
Not quite what you need but hopefully shows you what you can do.

class GenericExample
    {
        // generic method to change an array of value types to a list of strings
        public List<string> Convert<T>(T[] values) where T :struct, IConvertible
        {
            List<string> list = new List<string>();
            if (values != null)
            {
                for (int i = 0; i < values.Length; i++)
                {
                    list.Add(values[i].ToString());
                }
            }
            return list;
        }

        public void testConvert()
        {
            int[] ints = new int[] { 123, 456, 6789 };
            double[] doubles = new double[] { 12.34, 34.45, 777.345 };

            //test with integer array
            List<string> intlist = Convert<int>(ints);
            //test with double array
            List<string> doublelist = Convert<double>(doubles);
        }
    }

Neat Good approach. I'll do that.

Using nick's method I now have:

public static List<string[]> ConvertObjectArrayToStringArray<T>(T[] values) where T : struct, IConvertible
      {
         List<string[]> list = new List<string[]>();
         string[] stringArray = new string[values.Length];
         if (values != null)
         {
            for (int i = 0; i < values.Length; i++)
            {
               stringArray[i] = values[i].ToString();
            }
         }
         list.Add(stringArray);
         return list;
      }

I added a similar method to handle Generic lists that are Lists of typed arrays (eg List<double[]>).:

public static List<string[]> ToListStringArrayFromList<T>(List<T> list)
      {
         List<T> genericList = new List<T>(list);
         Array ar = genericList.ToArray();
         List<string[]> result = new List<string[]>();
         foreach (Array arInner in (Array)ar)
         {
               List<string> temp = new List<string>();
               foreach (object value in arInner)
               {
                  temp.Add(value.ToString());
               }
               string[] returnListElement = new string[temp.Count];
               for (int j = 0; j < temp.Count; j++)
               {
                  returnListElement[j] = temp[j];
               }
               result.Add(returnListElement);
         }

         return result;
      }

Now, to convert objects that may either be either typed arrays or generic lists of typed arrays I have a method that conditionally negotiates the transactions:

public static List<string[]> ToListString(object data)
      {
         string ty = data.GetType().Name;
         Type t = data.GetType().UnderlyingSystemType;
         List<string[]> result = new List<string[]>();

         if (t.IsGenericType)
         {
            Type[] typ = t.GetGenericArguments();
            string genericTypeName = typ[0].Name.ToString();
            switch (genericTypeName)
            {
               case "Double[]":
                  result = ToListStringArrayFromList((List<double[]>)data);
                  break;
               case "Int32[]":
                  result = ToListStringArrayFromList((List<int[]>)data);
                  break;
               //others...
               case "String[]":
                  {
                     result = (List<string[]>)data;
                     break;
                  }
            }
         }
         else
         {
            switch (data.GetType().Name)
            {
               case "String[]":
                     result.Add((string[])data);
                     break;
               case "Double[]":
                     result = ConvertObjectArrayToStringArray<double>((double[])data);
                     break;
               //others...
               case "Int[]":
                     result = ConvertObjectArrayToStringArray<int>((int[])data);
                     break;
            }
         }
         return result;
      }

Is there a more elegant way (better than testing types in my switch block) of properly typing the object before calling my List<string[]> creation methods?

Why not adjust the generic function to work with the IEnumerable, IList or ICollection type instead of object[] or List<object> types. Thay way it covers both lists and arrays.

public static List<string[]> ToListStringArrayFromList<T>(IList<T> list) where T: struct, IConvertible
{
   // code to create string list form IList object (using ForEach might be best)
}

Or event without genrics

public static List<string[]> ToListStringArrayFromList(IList list)
{
   // code to create string list form IList object (using ForEach might be best)
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.