2009-01-13 15 views
11

Estoy tratando de nuevo de una instancia de LocalCommand que es una clase privada de System.Data.SqlClient.SqlCommandSet. Parece que soy capaz de captar la información de tipo de bien:Activator.CreateInstance con la clase sellada privada

Assembly sysData = Assembly.Load("System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"); 
localCmdType = sysData.GetType("System.Data.SqlClient.SqlCommandSet+LocalCommand"); 

pero Activator.CreateInstance produce una excepción cuando intento crear una instancia:

object item = Activator.CreateInstance(localCmdType, 
    new object[] { commandText, parameters, num7, commandType }); 

System.MissingMethodException: Constructor del tipo 'Sistema .Data.SqlClient.SqlCommandSet + LocalCommand 'no encontrado.

Los argumentos de constructor coinciden con la firma que veo en el reflector. ¿Es nueva una clase privada con un ctor interno compatible con una sobrecarga CreateInstance diferente o qué?

Respuesta

18

Mi primer pensamiento sería obtener el ConstructorInfo usando ConstructorInfo constructorInfo = Type.GetConstructor(), y luego constructorInfo.Invoke() eso. Sospecho que Activator.CreateInstance hace que sea difícil llamar a constructores a los que normalmente no tendrías acceso, aunque no recuerdo haberlo intentado.

+2

Los documentos dicen CreateInstance sólo llama constructores públicos antes 2.0sp1. Después de eso, hay un montón de permisos que son necesarios. –

+1

Buena llamada en GetConstructor(), que funciona. Me resulta extraño teniendo en cuenta que la llamada a GetConstructor es muy similar a una de las sobrecargas Activator.CreateInstance(). –

18

Yo tengo que trabajar de esta manera:

using System; 
using System.Reflection; 

class Test 
{ 
    public String X { get; set; } 

    Test(String x) 
    { 
     this.X = x; 
    } 
} 

class Program 
{ 
    static void Main() 
    { 
     Type type = typeof(Test); 

     ConstructorInfo c = type.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, 
      null, new Type[] { typeof(String) }, null); 

     Object o = c.Invoke(new Object[] { "foo" }); 
    } 
} 

El truco era ir después del constructor específicamente con GetConstructor en lugar de tratar de encontrar en los resultados de GetConstructors. Imagínate.

+0

¡Gracias por el ejemplo! –

+0

¿Puede ser que esto no esté disponible en PCL? –

10

que podría ser un poco tarde en la respuesta, pero me encontré con un problema similar que encaja en este tema. Quería crear una instancia de un constructor no público utilizando Activator.CreateInstance y pasarle argumentos.

public class Node 
    { 
     string name; 
     Node parent; 
     protected Node(string name,Node parent) 
     { 
      this.name = name; 
      this.parent = parent; 
     } 
     public static Node Create(string name,Node parent) 
     { 
      Node result = Activator.CreateInstance(typeof(Node),BindingFlags.Instance | BindingFlags.NonPublic,null, new object[] { name, parent }, null) as Node; 
      return result; 
     } 

La parte complicada fueron las banderas de encuadernación. Mi primer instinto fue usar BindingFlags.CreateInstance | BindingFlags.NonPublic, sin embargo, provocó una excepción: No se encontró el constructor MissingMethodException en el tipo 'Node'. Disfrutar de

+0

Esto falla para mí con el error que describes pero, curiosamente, la respuesta de Andrew Hare sí funciona, aunque ambas respuestas comparten las mismas banderas vinculantes. – Jerther

+0

Simplemente no funciona. Como dijo Jerther, la respuesta de Andrew Hare sí. –

+0

¡Funcionó como un amuleto para mí! también he intentado usar '' 'BindingFlags.CreateInstance | BindingFlags.NonPublic''' y obtuvo el mismo mensaje de error.Cambiándolo a '' 'BindingFlags.Instance | BindingFlags.NonPublic''' lo hizo funcionar !! – Kaboo

0

truco es asegurarse de utilizar el derecho CreateInstance sobrecarga:

// WRONG 
... Activator.CreateInstance(
     type, 
     BindingFlags.Instance 
     | BindingFlags.NonPublic 
    ); 

Este llama a la sobrecarga de params, que por defecto a Instance | Public | CreateInstance, y se pasará sus banderas de unión como argumentos al constructor, dando el vago MissingMethodException.

Asimismo, el uso Instance | Public | NonPublic si no está seguro de la visibilidad del constructor:

// right 
... Activator.CreateInstance(
     type, 
     BindingFlags.Instance 
     | BindingFlags.Public 
     | BindingFlags.NonPublic, 
     null, 
     new object[] { }, // or your actual constructor arguments 
     null 
    ); 
Cuestiones relacionadas