Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
605 views
in Technique[技术] by (71.8m points)

reflection - c# Creating an unknown generic type at runtime

So I have a class that is a generic and it may need to, inside a method of its own, create an instance of itself with a different kind of generic, whose type is obtained through reflection.

This is important because this Repository maps T to a database table [it's an ORMish I am writing] and if the class that represents T has a collection representing ANOTHER table I need to be able to instance that and pass it to the repository [ala Inception].
I'm providing the method in case it makes it easier to see the problem.

private PropertiesAttributesAndRelatedClasses GetPropertyAndAttributesCollection() 
{
  // Returns a List of PropertyAndAttributes

  var type = typeof(T);
  //For type T return an array of PropertyInfo

  PropertiesAttributesAndRelatedClasses PAA = new PropertiesAttributesAndRelatedClasses();
  //Get our container ready

  //Let's loop through all the properties.
  PropertyAndAttributes _paa;
  foreach(PropertyInfo Property in type.GetProperties())
  {
    //Create a new instance each time.
    _paa = new PropertyAndAttributes();

    //Adds the property and generates an internal collection of attributes for it too
    _paa.AddProperty(Property);

    bool MapPropertyAndAttribute = true;
    //This is a class we need to map to another table
    if (Property.PropertyType.Namespace == "System.Collections.Generic")
    {
      PAA.AddRelatedClass(Property);
      //var x = Activator.CreateInstance("GenericRepository", Property.GetType().ToString());
    }
    else 
    {
      foreach(var attr in _paa.Attrs) 
      {
        if (attr is IgnoreProperty)
        {
          //If we find this attribute it is an override and we ignore this property.
          MapPropertyAndAttribute = false;
          break;
        }
      }
    }
    //Add this to the list.
    if (MapPropertyAndAttribute) PAA.AddPaa(_paa);
  }
  return PAA;
}

So given GenericRepository<T>, and I want to make a GenericRepository<string type obtained via reflection from the Property> how would I do this? The line I need to replace with something that WORKS is:

//var x = Activator.CreateInstance("GenericRepository", Property.GetType().ToString());

Thanks.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I think you're looking for the MakeGenericType method:

// Assuming that Property.PropertyType is something like List<T>
Type elementType = Property.PropertyType.GetGenericArguments()[0];
Type repositoryType = typeof(GenericRepository<>).MakeGenericType(elementType);
var repository = Activator.CreateInstance(repositoryType);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

56.8k users

...