Создание внутреннего класса и приведение его к заданному типу - PullRequest
2 голосов
/ 18 августа 2010

Вслед за InternalsVisibleTo . Я посмотрел на c # Создание класса Internal с помощью закрытого конструктора , и это помогло, но я пытаюсь преобразовать возвращаемый объект как внутренний тип, и, честно говоря, я не на 100% возможен.

Я пытаюсь решить проблему с помощью Reflection, но мне сложно разобраться, как создать экземпляр внутреннего типа с помощью закрытых методов с использованием отражения. Я могу зайти так далеко, чтобы вытащить тип и получить конструктор и создать объект.

Как бы я преформировал приведение объекта, если тип, который я хочу привести, является внутренним типом .?

public object InitPrivateCoreObjects(string Type)
{
    Assembly Core = Assembly.Load("Stuff.Core, Version=0.3.3881.21340, Culture=neutral, PublicKeyToken=4fe470e63e2d354e");
    Type TypeToReflect = Core.GetType("Stuff.Core.AssemblyWithIdentifer");
    object o = Activator.CreateInstance(TypeToReflect);
    MethodInfo mi = TypeToReflect.GetMethod("AssemblyWithIdentifer");
    object newObject = mi.Invoke(o,null);
    //alternatively
    //ConstructorInfo ctor = TypeToReflect.GetConstructor(new Type[]{TypeToReflect.GetType()});
    //ctor.Invoke(newObject, null);

    return newObject;
}

Я могу получить тип внутреннего класса,
Я могу вызвать конструктор и создать экземпляр объекта типа. Однако, поскольку у меня нет доступа к внутреннему типу, я не могу его привести и манипулировать им оттуда.

Я понимаю, что могу использовать Reflection.Emit для создания нового класса, основанного на этом типе, но если я иду по этому маршруту, я мог бы просто скопировать все содержимое проекта, к которому я пытаюсь получить доступ, в свой тестовый проект. Это было бы очень расточительно и бессмысленно и потребовало бы, чтобы я добавлял вещи из других проектов и создавал беспорядок, и это абсолютно не тот путь, по которому я хочу идти в это время.

Я видел примеры доступа к отдельным методам и свойствам, но ни одного из них, в которых описан целый класс. Я не уверен на 100%, что это возможно, так как в порядке операций отражение происходит до того, как рассматриваются модификаторы доступа.

Можно ли это сделать, и если да, то как?

Для удобства я хотел использовать экземпляр объекта для целей тестирования, а [Assembly:InternalsVisibleTo("")] не работал из-за ошибки, с которой я сейчас работаю. См. здесь для оригинального вопроса.

Ответы [ 3 ]

1 голос
/ 18 августа 2010

Я могу использовать Reflection.Emit для создания нового класса на основе этого типа

Не совсем: код, сгенерированный с использованием Reflection.Emit, следует тем же правилам, что и ваш собственный C #.Вы не можете использовать его для обхода internal защиты.

Я видел примеры доступа к отдельным методам и свойствам

Вот что вам нужно сделать:используйте рефлексию для поиска и вызова отдельных методов и свойств.

Несколько альтернатив:

  • Измените внутренний класс для реализации некоторого интерфейса и сделайте этот интерфейс общедоступным.Вызовите методы на интерфейсе как обычно.
  • Get [InternalsVisibleTo] работает. Это правильный путь.
1 голос
/ 18 августа 2010

Это не совсем прямой ответ на ваш вопрос, но вы можете найти это полезным:

ExposedObject

Если у вас нет доступа к внутреннему типу, и этот тип не реализует какой-либо открытый интерфейс, который вы считаете достаточным для взаимодействия с ним, , но вы заранее знаете имена и подписи членов этого типа, это, вероятно, ваш лучший выбор.

0 голосов
/ 18 августа 2010

Учитывая, что вы знаете тип только во время выполнения, на самом деле не существует такого понятия, как «возвращение объекта как внутреннего типа».Подумайте, как бы вы хотели, чтобы сигнатура метода выглядела ... Вы никак не могли бы выразить это.

Если вызывающий код знает об этом строго типизированным способом, вы должны сделать код универсальным:

public T InitPrivateCoreObjects<T>()
{
    Type type = typeof(T);
    ...
    return (T) newObject;
}

... но если вызывающий код не знает об этом, это бесполезно.

Если бы вы могли объяснить, почемувы думаете, что хотите эту способность, мы могли бы предложить альтернативные варианты.

...