Type wrongly reckognized ?

M

Milan

Hi experts,

Can someone help me to understand why inside function
"generic_func"
object of type "TS" is not reckognized as object of type "string"
but it is recognized as object of type "object" ?
later because of wrong type I get exception:

"Objekt of Type \"System.Collections.Generic.List`1[System.String]\" can not
be converted in Type \"System.Collections.Generic.List`1[System.Object]\".
How I can make that List<some_generic_type> reckognize type of TS correctly?


BR,
Milan.


class Matematician
{
public List<string> getSomeStringType()
{
List<string> lst_string = new List<string>();
return lst_string;
}
}

public void generic_func<TS, TM>(TS obj_string, TM obj_math)
{
Type tt = obj_string.GetType();
//correctly reckognized string type !{Name = "String" FullName =
"System.String"}

try
{
List<TS> obj_generic =
(List<TS>)obj_math.GetType().InvokeMember("getSomeStringType",
BindingFlags.Default | BindingFlags.InvokeMethod, null, obj_math, null);
}
catch (Exception ex)
{
//"Objekt of Type
\"System.Collections.Generic.List`1[System.String]\" can not be converted in
Type \"System.Collections.Generic.List`1[System.Object]\".
Console.WriteLine("error");
}
}

static void Main(string[] args)
{
Class1 obj_main = new Class1(); //Class1 holds main method !
string str_test_1 = "KingOfTheKongo";

object obj_math = new Matematician();
object obj_str = str_test_1;

// In real case (more coplicated)
// input parameters: obj_str, obj_math
// are created using reflection function
// Activator.CreateInstance
// and they are of type "object"
obj_main.generic_func(obj_str, obj_math);
}
 
P

Patrice

Interesting. It works when using string obj_str rather than object
obj_str...

Not sure why and bout to leave. Hopefully someone else will go further.. BTW
the overall goal may help. For example rather than using Reflection you
could perhaps use an interface. I tend to stay away from reflection unless
this is really needed...
 
B

Ben Voigt [C++ MVP]

Milan said:
Hi experts,

Can someone help me to understand why inside function
"generic_func"
object of type "TS" is not reckognized as object of type "string"
but it is recognized as object of type "object" ?
later because of wrong type I get exception:

"Objekt of Type \"System.Collections.Generic.List`1[System.String]\" can
not
be converted in Type \"System.Collections.Generic.List`1[System.Object]\".
How I can make that List<some_generic_type> reckognize type of TS
correctly?


BR,
Milan.


class Matematician
{
public List<string> getSomeStringType()
{
List<string> lst_string = new List<string>();
return lst_string;
}
}

public void generic_func<TS, TM>(TS obj_string, TM obj_math)
{
Type tt = obj_string.GetType();
//correctly reckognized string type !{Name = "String" FullName
=
"System.String"}

try
{
List<TS> obj_generic =
(List<TS>)obj_math.GetType().InvokeMember("getSomeStringType",
BindingFlags.Default | BindingFlags.InvokeMethod, null, obj_math, null);
}
catch (Exception ex)
{
//"Objekt of Type
\"System.Collections.Generic.List`1[System.String]\" can not be converted
in
Type \"System.Collections.Generic.List`1[System.Object]\".
Console.WriteLine("error");
}
}

static void Main(string[] args)
{
Class1 obj_main = new Class1(); //Class1 holds main method !
string str_test_1 = "KingOfTheKongo";

object obj_math = new Matematician();
object obj_str = str_test_1;

// In real case (more coplicated)
// input parameters: obj_str, obj_math
// are created using reflection function
// Activator.CreateInstance
// and they are of type "object"
obj_main.generic_func(obj_str, obj_math);

The compiler changes this line to match the static type of the arguments, a
call to generic_func<TS = object, TM = object>. So List<TS> means
List<object>.

Generics always use the static type of variables and NEVER use the runtime
type of object instances. (until C# 4.0 introduces the "dynamic" keyword,
which will make pretty much all reflection code using InvokeMember
obsolete).
 
M

Milan

Hi Ben,

thanks for answer but could you please:
1. explain me what does it means "static type of variables" is that declared
variable type which compiler finds with simple look back what is the type of
variable passed as argument ?
2. more important...how to convert without getting compiler error
List<string> to List<object> ?
List<string> lst_string = new List<string>();
List<object> lst_object = (List<object>)lst_string;

this question is equivalent as the line(just here I am getting exception
instead of compiler error):

List<TS> obj_generic =
(List<TS>)obj_math.GetType().InvokeMember("getSomeStringType",
BindingFlags.Default | BindingFlags.InvokeMethod, null, obj_math, null);


Best regards,
Milan.



Ben Voigt said:
Milan said:
Hi experts,

Can someone help me to understand why inside function
"generic_func"
object of type "TS" is not reckognized as object of type "string"
but it is recognized as object of type "object" ?
later because of wrong type I get exception:

"Objekt of Type \"System.Collections.Generic.List`1[System.String]\" can
not
be converted in Type \"System.Collections.Generic.List`1[System.Object]\".
How I can make that List<some_generic_type> reckognize type of TS
correctly?


BR,
Milan.


class Matematician
{
public List<string> getSomeStringType()
{
List<string> lst_string = new List<string>();
return lst_string;
}
}

public void generic_func<TS, TM>(TS obj_string, TM obj_math)
{
Type tt = obj_string.GetType();
//correctly reckognized string type !{Name = "String" FullName
=
"System.String"}

try
{
List<TS> obj_generic =
(List<TS>)obj_math.GetType().InvokeMember("getSomeStringType",
BindingFlags.Default | BindingFlags.InvokeMethod, null, obj_math, null);
}
catch (Exception ex)
{
//"Objekt of Type
\"System.Collections.Generic.List`1[System.String]\" can not be converted
in
Type \"System.Collections.Generic.List`1[System.Object]\".
Console.WriteLine("error");
}
}

static void Main(string[] args)
{
Class1 obj_main = new Class1(); //Class1 holds main method !
string str_test_1 = "KingOfTheKongo";

object obj_math = new Matematician();
object obj_str = str_test_1;

// In real case (more coplicated)
// input parameters: obj_str, obj_math
// are created using reflection function
// Activator.CreateInstance
// and they are of type "object"
obj_main.generic_func(obj_str, obj_math);

The compiler changes this line to match the static type of the arguments, a
call to generic_func<TS = object, TM = object>. So List<TS> means
List<object>.

Generics always use the static type of variables and NEVER use the runtime
type of object instances. (until C# 4.0 introduces the "dynamic" keyword,
which will make pretty much all reflection code using InvokeMember
obsolete).
 
M

Milan

Never run for the bus ! :)
In this direction you have right, argument pointer variable TS is of the
type "object" and object self is of type "string", BUT with all this
knowledge how we can integrate type "t_ojb_str" into "List<TS>" so that I do
not get exception ?


public void generic_func<TS, TM>(TS obj_string, TM obj_math)
{
Type t_ts = typeof(TS);
//{Name = "Object" FullName = "System.Object"}

Type t_ojb_str = obj_string.GetType();
//{"Name = "String" FullName = "System.String"}

List<TS> obj_generic =
(List<TS>)obj_math.GetType().InvokeMember("getSomeStringType",
BindingFlags.Default | BindingFlags.InvokeMethod, null, obj_math, null);

}

Thanks and regards,
Milan.
 
P

Patrice

What do you want to do is a bit unclear so it's not that easy to give a
specific advice...

As it seems that you assumed TS would always be a string you may want
perhaps to use a signature such void generic_func<TM>(string obj_string, TM
obj_math) and accordingly use a string rather than an object at call
time...
 
M

Milan

Hi Patrice,

since I am reading diffrent types from DB it must be generic and mention
type string is just simplification it can be in practice any type. So using
Interface will not avoid using generics because of diffrent types comming
from DB.

1. Using constraints maybe but constraints also need type, right ?

2. Introducing reflection in C# but not introducing way of dynamic passing
variable-object types to function in order to use them for casting seems as
unfinished job. Do I see it wrong ? I am just beginner in C# so sorry for
maybe stupid questions.


Best regards,
Milan.
 
P

Patrice

You could also use generics this way :

class Matematician<T>
{
public List<T> getSomeStringType()
{
List<T> lst_string = new List<T>();
return lst_string;
}
}

static void Main(string[] args)
{
Matematician<string> o1=new Matematician<string>();
Matematician<int> o2=new Matematician<int>();
}

http://blogs.msdn.com/cburrows/archive/2008/10/27/c-dynamic.aspx could
perhaps help to avoid doing too much work that would be no more needed in C#
4...

Not sure why you need such a requirement but at some point it's hard anyway
to do something when you know nothing about the type you are using. For
example even if you get a list of unknown object what will you do against
them ? What are the operation you'll do against those objects ?

At this step, it's likely your best bet is to explain what you are trying to
do.
 
T

Tim Roberts

Milan said:
thanks for answer but could you please:
1. explain me what does it means "static type of variables" is that declared
variable type which compiler finds with simple look back what is the type of
variable passed as argument ?

Yes. In your example:
object obj_math = new Matematician();
object obj_str = str_test_1;

obj_main.generic_func(obj_str, obj_math);

The two parameters are of type object, so this compiles to a call to
2. more important...how to convert without getting compiler error
List<string> to List<object> ?
List<string> lst_string = new List<string>();
List<object> lst_object = (List<object>)lst_string;

You have to copy the contents one by one. There are several ways to do
that.
 
Top