48

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?

Lauren Rutledge
  • 1,195
  • 5
  • 18
  • 27

2 Answers2

29

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);
OxCantEven
  • 629
  • 4
  • 9
16

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

Community
  • 1
  • 1
ProfFan
  • 178
  • 1
  • 8