Я пытаюсь создать экземпляр LocalCommand, который является частным классом System.Data.SqlClient.SqlCommandSet. Кажется, я могу просто получить информацию о типе:
Assembly sysData = Assembly.Load("System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
localCmdType = sysData.GetType("System.Data.SqlClient.SqlCommandSet+LocalCommand");
но Activator.CreateInstance выдает исключение, когда я пытаюсь создать его экземпляр:
object item = Activator.CreateInstance(localCmdType,
new object[] { commandText, parameters, num7, commandType });
System.MissingMethodException: конструктор типа System.Data.SqlClient.SqlCommandSet + LocalCommand не найден.
Аргументы конструктора соответствуют подписи, которую я вижу в Reflector. Новый закрытый класс с внутренним ctor поддерживается с другой перегрузкой CreateInstance или как?





Моей первой мыслью было бы получить ConstructorInfo с использованием ConstructorInfo constructorInfo = Type.GetConstructor(), а затем constructorInfo.Invoke(). Я подозреваю, что Activator.CreateInstance затрудняет вызов конструкторов, к которым у вас обычно нет доступа, хотя я не помню, чтобы пробовал это сам.
Хороший вызов GetConstructor (), это работает. Мне это кажется странным, учитывая, что вызов GetConstructor очень похож на одну из перегрузок Activator.CreateInstance ().
Я заставил это работать так:
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" });
}
}
Уловка заключалась в том, чтобы искать конструктор специально с GetConstructor, а не пытаться найти его в результатах GetConstructors. Иди разберись.
Может быть, это недоступно в PCL?
Возможно, я немного запоздал с ответом, но я столкнулся с аналогичной проблемой, которая укладывается в эту тему.
Я хотел создать экземпляр непубличного конструктора с помощью Activator.CreateInstance и передать ему аргументы.
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(
type: typeof(Node),
bindingAttr: BindingFlags.Instance | BindingFlags.NonPublic,
binder: null, //default binder
args: new object[] { name, parent },
culture: null);
return (Node)result;
}
}
Сложность заключалась в привязке флажков.
Моим первым побуждением было использовать BindingFlags.CreateInstance | BindingFlags.NonPublic, однако это вызвало исключение: Конструктор MissingMethodException для типа «Узел» не найден.
Это не удается для меня с ошибкой, которую вы описываете, но, как ни странно, ответ Эндрю Хейра действительно работает, хотя оба ответа имеют одни и те же флаги привязки.
Просто не работает. Как сказал Джертер, отвечает и ответ Эндрю Хейра.
Сработало для меня как шарм! Я тоже пробовал использовать BindingFlags.CreateInstance | BindingFlags.NonPublic и получил то же сообщение об ошибке. Поменяв его на BindingFlags.Instance | BindingFlags.NonPublic, он заработал !!
Уловка заключается в том, чтобы использовать правильную перегрузку CreateInstance:
// WRONG
... Activator.CreateInstance(
type,
BindingFlags.Instance
| BindingFlags.NonPublic
);
Это вызывает перегрузку params, которая по умолчанию будет Instance | Public | CreateInstance, и ваши флаги привязки будут переданы в качестве аргументов конструктору, давая расплывчатый MissingMethodException.
Также используйте Instance | Public | NonPublic, если вы не уверены в видимости конструктора:
// right
... Activator.CreateInstance(
type,
BindingFlags.Instance
| BindingFlags.Public
| BindingFlags.NonPublic,
null,
new object[] { }, // or your actual constructor arguments
null
);
В документах говорится, что CreateInstance вызывает только общедоступные конструкторы до 2.0sp1. После этого необходим набор разрешений.