0

Sorry for my English Miserables.

I have 2 values ​​from an XML file and I need it to a generic method further lead to the return-value T. In one XML value is of this type, but how can I use this as a Type?

example:

var dataType = xml.Element("type").Value;
var modelList = await Mapper<dataType>(serviceXml, myNamespace, objType, serviceJson.ToString());
David
  • 208,112
  • 36
  • 198
  • 279
  • You can get a `Type` from a string using `Type.GetType()` but I don't think there's any way to use it as a *type parameter* since that needs to be known at compile-time. Does `Mapper()` have an overload which accepts a method parameter of type `Type` instead? (Or can it?) – David Oct 20 '14 at 13:06
  • Most mappers can receive the type as a parameter where you can use the .GetType() method – Amorphis Oct 20 '14 at 13:06
  • @David ... not true, you could use reflection to make a generic call, example: http://stackoverflow.com/questions/232535/how-to-use-reflection-to-call-generic-method –  Oct 20 '14 at 13:06
  • @AndreasNiedermair In which case you will need the Type to make the generic call – samy Oct 20 '14 at 13:08
  • @AndreasNiedermair: Good point, I've never tried that for a type parameter but it makes sense that it would be possible. Perhaps not ideal, but possible. If the `Mapper` can accept a `Type` that's probably still preferred anyway. – David Oct 20 '14 at 13:08
  • @samy which you'll get by `Type.GetType` - am I missing something? –  Oct 20 '14 at 13:08
  • Not at all, I was answering your comment which seemed to imply that getting the type through Type.GetType was not correct to use the Mapper – samy Oct 20 '14 at 13:09
  • What is your further execution-path, what are you doing with `modelList`? I am not 100% sure if this is how your underlying problem could be solved... If you need to return `T`, why do you want to do explicit typing here? Either your call should be generic or explicit - this current mix does not make sense! –  Oct 20 '14 at 13:22

3 Answers3

1

1) Load type with Type.GetType

2) Use reflection to create generic Mapper, i.e. typeof(Mapper<>).CreateGenericType(dataType)

3) Use Activator.CreateInstance to create instance of generic Mapper

Andrew Karpov
  • 431
  • 2
  • 7
0

You can use the static GetType method that takes a string and return a Type if it can be found

Type.GetType("System.Collections.Generic.Dictionary`2[System.String,[MyType,MyAssembly]]")

If the type represented by the string cannot be found, it will return null

After getting the type, you can use the Mapper through reflection: if Mapper is a method then use the following

MethodInfo method = this.GetType().GetMethod("Mapper"); // this.GetType works if you aren't in a static method
MethodInfo generic = method.MakeGenericMethod(Type.GetType("theXmlValue"));
generic.Invoke(this, new object[] {/* your parameters to the Mapper method */}); 
samy
  • 14,832
  • 2
  • 54
  • 82
  • but ... the mapper has to provide a method with a `Type`-parameter (non-generic) –  Oct 20 '14 at 13:05
  • 1
    @AndreasNiedermair Then the mapper will need to be called by reflection, by making the class generic, which will need the type anyway. – samy Oct 20 '14 at 13:07
  • ?? ... you should enhance your answer by giving a hint for either going for a non-generic overload or using reflection to make a generic call. currently this answer is just half of the way ... btw i'm not the downvoter ;) –  Oct 20 '14 at 13:09
  • nearly perfect edit, but did you see the `await`-keyword? does that have any impact on the reflection part? –  Oct 20 '14 at 13:14
  • @AndreasNiedermair I was currently thinking about the invoke result: how to cast it to the correct expected type. Didn't think about the await yet. Don't hesitate to pitch in though ;) – samy Oct 20 '14 at 13:16
  • @AndreasNiedermair I'd say no at first glance: http://blogs.msdn.com/b/pfxteam/archive/2013/03/13/quot-invoke-the-method-with-await-quot-ugh.aspx From what I see this would be like evaluating the Mapper, then awaiting it, unless Mapper returns a Task? Mapper is a bit under-undefined no? – samy Oct 20 '14 at 13:19
  • @AndreasNiedermair With pleasure, let's – samy Oct 20 '14 at 13:26
  • despite your effort - I am struggeling with the same issue, the result of the mapping itself. I've already added a comment to the question, because I do not think that the OP is telling us the whole picture and that the current implementation is a misuse of generics. –  Oct 20 '14 at 13:27
0

You can't use a type variable as a parameter in a generic method. The type must be known at compile time. You can do it through reflection by calling a method created using the MakeGenericMethod call. I think it would look something like this:

var method = Mapper.GetType().GetMethod("DoesEntityExist")
                         .MakeGenericMethod(new Type[] { dataType });
method.Invoke(this, new object[] { serviceXml, myNamespace, objType, serviceJson.ToString() });

What you could do is create an interface or a base class and create an extension method to handle the conversion.

Allan Elder
  • 4,052
  • 17
  • 19