Вопрос:

Как использовать внутренний класс другой сборки

c# .net oop .net-assembly

10892 просмотра

5 ответа

46 Репутация автора

У меня есть сторонняя сборка, и я хотел бы использовать ее Internalкласс в моем новом проекте на C #. Является ли это возможным?

Любой пример будет по достоинству оценен

Автор: user1878422 Источник Размещён: 06.12.2014 04:52

Ответы (5)


11 плюса

17705 Репутация автора

внутренняя: доступ к типу или элементу может получить любой код в той же сборке, но не из другой сборки.

Вы не можете использовать внутренние классы других сборок, цель использования internal модификатора доступа - сделать его доступным только внутри сборки определенным классом.

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

[assembly: InternalsVisibleTo("name of assembly here")]

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

Предположим, у вас есть эта DLL (mytest.dll сказать):

using System; 

namespace MyTest 
{ 
      internal class MyClass 
      {  
          internal void MyMethod() 
          {  
               Console.WriteLine("Hello from MyTest.MyClass!"); 
          } 
      } 
} 

и вы хотите создать экземпляр MyTest.MyClassи затем вызвать MyMethod()из другой программы, используя отражение. Вот как это сделать:

using System; 
using System.Reflection;

namespace MyProgram 
{ 
    class MyProgram 
    { 
          static void Main() 
          { 
              Assembly assembly = Assembly.LoadFrom("mytest.dll");
              object mc = assembly.CreateInstance("MyTest.MyClass");
              Type t = mc.GetType(); 
              BindingFlags bf = BindingFlags.Instance |  BindingFlags.NonPublic;
              MethodInfo mi = t.GetMethod("MyMethod", bf); 
              mi.Invoke(mc, null); 
              Console.ReadKey(); 
         } 
    } 
}  
Автор: Hamid Pourjam Размещён: 06.12.2014 04:55

2 плюса

22135 Репутация автора

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

Дружественная сборка - это сборка, которая может получить доступ к другим типам и членам дружественной (Visual Basic) или внутренней (C #) сборки. Если вы идентифицируете сборку как сборку друга, вам больше не нужно отмечать типы и элементы как общедоступные, чтобы к ним могли обращаться другие сборки.

Вы можете использовать отражение, хотя: Как получить доступ к внутреннему классу, используя Reflection

В любом случае не рекомендуется.

Автор: vtortola Размещён: 06.12.2014 04:56

1 плюс

111 Репутация автора

Ты не можешь сделать это. Посмотрите здесь: Уровни доступности (C # Reference)

Автор: Miroslav Endyš Размещён: 06.12.2014 04:56

2 плюса

2213 Репутация автора

Если это внутренний класс, то разработчик не хочет, чтобы вы использовали его. Если вы хотите использовать часть этого кода, просто используйте Reflector и переместите его в новый класс. Использовать внутренние или закрытые классы небезопасно, поскольку разработчик не думает о том, чтобы кто-либо, кроме себя, использовал его, и в будущем они могли бы вносить изменения, которые нарушали бы функциональность, они могли бы не быть поточно-ориентированными и т. Д. Поэтому следует просто уважать их дизайн.

Автор: Murven Размещён: 06.12.2014 04:57

7 плюса

17850 Репутация автора

Если вы не можете изменить и перекомпилировать библиотеку, взгляните на ImpromptuInterface.

https://www.nuget.org/packages/ImpromptuInterface/

Пример:

namespace ImpromptuExample
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // Get the desired type
            Type typeObject = typeof(SampleLibrary.PublicClass).Assembly.GetType("SampleLibrary.SamplePrivateClass");
            // todo:  add error handling if typeObject is null

            // Create an instance
            object instance = Activator.CreateInstance(typeObject);
            ITest wrappedInstance = ImpromptuInterface.Impromptu.ActLike<ITest>(instance);
            MessageBox.Show(wrappedInstance.TestMethod(textBox1.Text));
        }

        public interface ITest
        {
            string TestMethod(string name);
        }
    }
}

namespace SampleLibrary
{
    public class PublicClass
    {
    }

    class SamplePrivateClass
    {
        public string TestMethod(string name)
        {
            return string.Concat("Hello ", name);
        }
    }
}

Внутренне, что ImpromptuInterface делает, чтобы создать динамическую сборку в памяти и внутри этой сборки, он создает прокси-класс, который реализует запрошенный интерфейс (ы) и передает вызовы методов и свойства между ними. В бэкэнде он все еще использует отражение, но это немного более приятная инкапсуляция, чем все это через собственное отражение.

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

Полезные функции, в том числе: динамический прокси-класс сопоставляет свойства с полями, вы можете сопоставить методы интерфейса с закрытыми, защищенными и внутренними методами в исходном классе. Однако он не работает со статическими классами методов.

Автор: John Размещён: 06.12.2014 05:07
Вопросы из категории :
32x32