I'm trying to write a generic method to sort 2-dimensional arrays. I'm converting each row in the array to a delimited string, which I then add to an ArrayList and then use the ArrayList.Sort() method.
The problem I'm having is in then casting the objects in the sorted ArrayList back to the original type.
This is the code:
Type type = typeof(T);
sortedArray[rowIndex, columnIndex] = (type) delimitedFields[columnIndex];
I'm getting this error:
The type or namespace name 'type' could not be found (are you missing a using directive or an assembly reference )
I can't work out what I'm missing.
I have the following using directives:
using
System;using
System.Collections.Generic;using
System.Collections;using
System.Text;using
System.Reflection;So I'm missing something... I just don't know what.

Generics & Type Casting
Googlesyrop
Thanks for the replies. The struct constraint is what I'm after, but the problem I'm having now is casting from a string back to <T> the original type.
So, in the test I am trying I take an array of ints, convert to strings to sort, but then I want to cast each string back to int.
In order to do
T obj = s as T;
I need the "class" constraint. But I want to work with base value types only.
So my options seem to be to work with objects only
Or do I have implement the IConvertible interface and come up with my own ConvertToT method
Help is much appreciated.
carthegenian
I'm not aware of "OR"ing constraints, only "AND"ing.
As a workaround, you could put add to your generic class method a System.Diagnostics.Debug.Assert() to check that T.GetType() is one of the allowed types.
Brian
Liel
In your sample code try changing the 2nd line in the method to "T temp = (T)s;", it should work. I did a simple test on similar lines by declaring a generic class with struct constraint:
public class Class2<T> where T : struct< xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
{
T secondVar;
string strVar;
public T Test(T firstVar)
{
strVar = firstVar.ToString();
secondVar = (T)firstVar;
return secondVar;
}
}
Test() method simply did a convesion like you tried with a 2-D array. Finally I tested this code with a button on a form:
Class2<int> obj = new Class2<int>();
MessageBox.Show(obj.Test(5).ToString());
alshami
You can't cast string to int because they are not compitable type. That's why int, double, DateTime etc have Parse method and you can pass in a string and extract data of the correct type. We can use this knowledge, and invoke the Parse method using the reflection. What I have done in CastTest class is wrote a private method to parse out the value from the string:
public class CastTest<T> where T : struct
{
T newT;
string s;
public T Test(T item)
{
s = item.ToString();
newT = Parse(s);
return newT;
}
private T Parse(string s)
{
Type t = typeof(T);
System.Reflection.MethodInfo parseMethod = t.GetMethod("Parse", new Type[] { typeof(string) });
if (parseMethod != null)
return (T)parseMethod.Invoke(null, new object[] { s });
else
throw new ApplicationException(t.Name + " type does not support Parse() method.");
}
}
This was a very good learning exercise for me too.
GuyLowndes
Sueva
You are right, I don't know what I was thinking, sorry about that. I will keep thinking about this, in the mean time, instead of using a string type for "s", using an object type seems to let you cast back to the appropriate type.
public class CastTest<T> where T : struct
{
T newT;
object s;
public T Test(T item)
{
s = item;
newT = (T)s;
return newT;
}
}
haal1
To limit to only value types you can use struct constraint:
yourclass<T> where T : struct
DOAHunterX
jeremym1234
Thanks - that's very helpful.
I had considered the Parse method earlier on, but hadn't a clue where to start with writing a custom version of it. I thought that if it seemed too complicated there must have been an easier way to do it.
However, this is very useful information.
Thanks for all your help!
James
bobiav
No worries! Thanks for your continued attention.
Of course I can compare objects, the original goal of this was get a 2d Array into an ArrayList (as a delimited string), sort it (with the necessary methods to sort by a certain column) then split out each string and add them back to the original T[,] Array.
In any case, in the meantime I've written the QuickSort to work with 2d Arrays and sort by selected column - so as a learning exercise (which is all this is) it has certainly been useful.
I'd be interested to know why you can't cast back to <T> from string. I wonder if it is because string is nullable
Anyway, thanks for your help so far.
James
clarayeung
Thanks, but I can't get that to work - still get the Cannot convert "string" to "T" error.
public class CastTest<T> where T : struct
{
T newT;
string s;
public T Test(T item)
{
s = item.ToString();
newT = (T) s;
return newT;
}
}
public class Tester
{
static void Main()
{
int i = 5;
CastTest<int> ct = new CastTest<int>();
int j = ct.Test(i);
Console.WriteLine(j.GetType().ToString());
}
}
Server Girl
Thanks for the response. Unfortunately it doesn't work - I think because I know nothing about Generics and am having problems with constraints.
I want restrict the 2-dimensional array to vase* value types only - so: int, string, double etc.
It doesn't seem that this is possible. Any thoughts
Thanks,
James
*edit: base, not vase
AlexTorone
Type type = typeof(T);
makes type a variable not a type.
Try:
sortedArray[rowIndex, columnIndex] = (T) delimitedFields[columnIndex];
or a bit more elegantly:
sortedArray[rowIndex, columnIndex] = delimitedFields[columnIndex] as T;
ArifKh
Apologies, here you go:
public void CastTest(T[,] tObject)
{
string s = tObject[0,0].ToString();
T temp = s as T;
tObject[0,0] = temp;
}
Where tObject is a 2d array of value types (so ints, doubles etc...)