Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use local variable as a type? Compiler says "it is a variable but is used like a type"

Tags:

c#

reflection

At run-time, I don't know what type of variable v1 is. For this reason, I wrote many if else statements:

if (v1 is ShellProperty<int?>) {     v2 = (v1 as ShellProperty<int?>).Value; } else if (v1 is ShellProperty<uint?>) {     v2 = (v1 as ShellProperty<uint?>).Value; } else if (v1 is ShellProperty<string>) {     v2 = (v1 as ShellProperty<string>).Value; } else if (v1 is ShellProperty<object>) {     v2 = (v1 as ShellProperty<object>).Value; }     

The only difference is in ShellProperty<AnyType>.

So instead of writing this with a lot of if else statements, I decided to use reflection to get the property type at run-time:

 Type t1 = v1.GetType().GetProperty("Value").PropertyType;  dynamic v2 = (v1 as ShellProperty<t1>).Value; 

This code gets the PropertyType of v1 and assigns it to the local variable t1, but after that, my compiler says that:

t1 is a variable but is used like a type

So it does not allow me to write t1 inside ShellProperty<>.

Please tell me how to solve this problem and how to get more compact code than what I have. Do I need to create a new class?

like image 443
IremadzeArchil19910311 Avatar asked Oct 04 '15 15:10

IremadzeArchil19910311


Video Answer


2 Answers

You were very close, you were just missing a call to MakeGenericType.

I believe your code would look like the following:

Type t1 = v1.GetType().GetProperty("Value").PropertyType; var shellPropertyType = typeof(ShellProperty<>); var specificShellPropertyType = shellPropertyType.MakeGenericType(t1); dynamic v2 = specificShellPropertyType.GetProperty("Value").GetValue(v1, null); 

Edit: As @PetSerAl pointed out I added some layers of indirection that were unnecessary. Sorry OP, you probably want a one liner like:

dynamic v2 = v1.GetType().GetProperty("Value").GetValue(v1, null); 
like image 188
OxCantEven Avatar answered Sep 21 '22 06:09

OxCantEven


For generics, you have to create them dynamically.

MethodInfo method = typeof(Sample).GetMethod("GenericMethod"); MethodInfo generic = method.MakeGenericMethod(myType); generic.Invoke(this, null); 

To create a generic object, you can

var type = typeof(ShellProperty<>).MakeGenericType(typeof(SomeObject)); var v2 = Activator.CreateInstance(type); 

Please refer to Initializing a Generic variable from a C# Type Variable

like image 29
ProfFan Avatar answered Sep 21 '22 06:09

ProfFan