我有一个第三方程序集,我想在我的新 C# 项目中使用它的
Internal
类。
可以吗?
任何例子都将不胜感激
内部:类型或成员可以由同一组中的任何代码访问 程序集,但不是来自另一个程序集。
您不能使用其他程序集的内部类,使用
internal
访问修饰符的目的是使其在类定义的程序集中可用。
如果您有权访问程序集代码并且可以修改它,您可以将第二个程序集作为当前程序集的朋友,并使用以下属性标记程序集
[assembly: InternalsVisibleTo("name of assembly here")]
如果没有,您始终可以使用反射,但请注意,在第 3 方程序集上使用反射是危险的,因为它可能会被供应商更改。如果可能的话,您还可以反编译整个程序集并使用您想要的部分代码。
假设你有这个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();
}
}
}
如果您无法修改和重新编译库,请查看 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 所做的是在内存中创建一个动态程序集,并在该程序集中创建一个代理类,该代理类实现所请求的接口并在两者之间中继方法调用和属性。在后端,它仍然使用反射,但它的封装比通过您自己的反射完成这一切要好一些。
显然,这涉及到开销,但如果您没有其他选择,这是一个可行的最后手段。
有用的功能,包括:动态代理类将属性映射到字段,可以将接口方法映射到原始类中的私有、受保护和内部方法。然而,它不适用于静态方法类。
您必须创建一个友好的程序集,但您需要重新编译该第三方程序集:
友元程序集是可以访问另一个程序集的程序集 友元 (Visual Basic) 或内部 (C#) 类型和成员。如果你 将程序集识别为友元程序集,您不再需要标记 类型和成员为公共,以便其他人可以访问它们 组件。
您可以使用反射:如何使用反射访问内部类
反正不推荐。
如果是内部类,那么开发者不希望你使用它。如果您想使用此代码的一部分,只需使用 Reflector 并将其移至新类即可。使用内部或私有类是不安全的,因为开发人员不会想到除了他们自己之外的任何人使用它,并且他们可能会在将来进行更改来破坏功能,它们可能不是线程安全的,等等。所以你应该只是尊重他们的设计。
你不能那样做。 请看这里:辅助功能级别(C# 参考)