0

I've got following struct and I need to create an instance of it through System.Reflection . The big issue is that I have a generic and a non generic parameter. I have to use System.Reflection because it'll be called in a loop where T can vary. I've looked at this , but I was unabled to get it work with the second parameter (int tag). I'm sorry that I have to ask this basic question.

struct pair<T>
{
    public pair(T value,int tag)
    {...}
}

so I would need the magic in this:

 object createPair(object o,int tag)
 {
   return *somemagic*
 }

EDIT: the solution was making the struct public in combination with the first answer. If a struct is nested in a generic struct, both answers throw an ArgumentException, independent of the input. I'm sorry for not knowing this affect of nesting.

Community
  • 1
  • 1
leAthlon
  • 734
  • 1
  • 10
  • 22
  • 2
    This smells like the [XY Problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). Perhaps try explaining what you're trying to do rather than what you want done. – Yuval Itzchakov May 14 '15 at 19:54
  • Thought it would be too long and not good to explain. I want to create something like a Dictionary with multiple keys and the possibility to add objects with the same key. It shall return an Array of objects which match to the given keys. The number of keys should be variable. I'm not allowed to change anything in the pair struct because of project restrictions. – leAthlon May 14 '15 at 20:08
  • Are you talking about using the _type_ of each object as the object's Key, or allowing an arbitrary (but collision-allowed) Key object? – David May 14 '15 at 20:16
  • I'm talking about second one. – leAthlon May 14 '15 at 20:22

2 Answers2

3

The reason the linked answer works is because that overload of Activator.CreateInstance hooks into parameterless, public constructors, also known as the default constructor.

However, that same method has overloads which include a signature which accepts parameters.

public object CreatePair(object t, int tag)
{
    var type = t.GetType();
    var targetType = typeof(Pair<>).MakeGenericType(type);
    return Activator.CreateInstance(targetType, t, tag);
}
David
  • 10,458
  • 1
  • 28
  • 40
  • `var targetType = typeof(Pair<>).MakeGenericType(type);` throws an ArgumentException because the number of Arguments mismatch – leAthlon May 14 '15 at 20:05
  • Problem still exists at the same position. – leAthlon May 14 '15 at 20:11
  • according to https://dotnetfiddle.net/XulN1e this code should run fine. If there's something different about your source, please update your answer. – David May 14 '15 at 20:14
  • "The number of generic arguments provided doesn't equal the arity of the generic type definition."-ArgumentException – leAthlon May 14 '15 at 20:15
  • Got it work through making the stuct public. I have poorly no plan why, but it works. – leAthlon May 14 '15 at 20:22
2

Make the input type generic using the MakeGenericType method:

object createPair(object obj,int tag) {
   Type type = typeof(Pair<>);
   Type genericType = type.MakeGenericType(obj.GetType());
   return Activator.CreateInstance(genericType, obj, tag);
}

But I would use generics instead of reflection if it was possible.

Mehrzad Chehraz
  • 5,092
  • 2
  • 17
  • 28
  • @leAthlon what do you send it as argument? – Mehrzad Chehraz May 14 '15 at 19:58
  • note that since that signature declares `params object[]`, it thinks you're looking for a `.ctor(object[])`, not `.ctor(T)` - try removing the `new object[]` and passing the argument directly. Also note that the .ctor has two arguments, `T` and `int`, and you need to pass the int as well. – David May 14 '15 at 19:59
  • @Mehrzad Chehraz `createPair(typeof(string),0)` the problem is that in your solution you only send the 0 to the constructor not the generic variable. – leAthlon May 14 '15 at 20:01
  • 0 is a int and should be the tag. – leAthlon May 14 '15 at 20:10
  • still the same Exception. – leAthlon May 14 '15 at 20:14
  • "The number of generic arguments provided doesn't equal the arity of the generic type definition."-ArgumentException – leAthlon May 14 '15 at 20:21
  • if you want to look at the Exception [there it is](https://dotnetfiddle.net/VQJZKO) – leAthlon May 15 '15 at 11:16
  • @leAthlon Well you have made things much complicated by using two nested generic classes, one is "t" and another is "T". So the accepted answer (and also mine) does not apply to this case, If you want an answer for that case, update your question (including the code) so I can update mine. – Mehrzad Chehraz May 15 '15 at 13:45
  • If you get the nested one working I'll create a new one. I only got it working through "unnesting" it and making them public. I was told in school that class nesting would only affect the visibility of the inner class and would be used to hide classes in Intellisense. But this example showed me that it's not the only effect. – leAthlon May 15 '15 at 14:06
  • @leAthlon I can make that nested sample work, but your intention of what you are actually doing by that code is unclear to me. – Mehrzad Chehraz May 15 '15 at 14:29
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/77907/discussion-between-leathlon-and-mehrzad-chehraz). – leAthlon May 15 '15 at 14:36