c# reflection ado.net

c# - Activator.CreateInstance con clase privada sellada



reflection ado.net (4)

Mi primer pensamiento sería obtener 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.

Estoy intentando actualizar una instancia de LocalCommand que es una clase privada de System.Data.SqlClient.SqlCommandSet. Parece que soy capaz de tomar la información del tipo muy bien:

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 arroja una excepción cuando intento instanciarlo:

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

System.MissingMethodException: No se encontró Constructor en el tipo ''System.Data.SqlClient.SqlCommandSet + LocalCommand''.

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


Lo tengo para 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 fue ir tras el constructor específicamente con GetConstructor lugar de tratar de encontrarlo en los resultados de GetConstructors . Imagínate.


Es posible que llegue un poco tarde para responder, 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 difícil fue las banderas vinculantes. 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


El truco es asegurarse de usar la sobrecarga CreateInstance correcta:

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

Esto llama a la sobrecarga de params , que se configurará por defecto en Instance | Public | CreateInstance Instance | Public | CreateInstance Instance | Public | CreateInstance , y sus banderas de enlace se pasarán como argumentos al constructor, dando la vaga MissingMethodException .

Además, use Instance | Public | NonPublic Instance | Public | NonPublic 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 );