繁体   English   中英

如何使用反射从静态方法中调用实例类方法

[英]How to call an instance class method from a static method with reflection

namespace ClassLibraryB {
    public class Class1 {
        public void Add(int ii, int jj)
        {
            i = ii;
            j = jj;
            result = i + j;
        }
        public void Add2()
        {
            result =  i + j;
        }
    }
}

这被称为静态,并给我一个答案

ClassLibraryB.Class1 objB = new ClassLibraryB.Class1();
objB.Add(4, 16);
objB.Add2();
kk = objB.result;
textBox1.Text += "Addition =" + kk.ToString() + "\r\n";

但是,当我尝试使用下面的方法调用dll时,它失败了,因为它不是静态的

Assembly testAssembly = Assembly.LoadFile(strDLL);
Type calcType = testAssembly.GetType("ClassLibraryB.Class1");
object calcInstance = Activator.CreateInstance(calcType);
PropertyInfo numberPropertyInfo = calcType.GetProperty("i");
numberPropertyInfo.SetValue(calcInstance, 5, null);
PropertyInfo numberPropertyInfo2 = calcType.GetProperty("j");
numberPropertyInfo2.SetValue(calcInstance, 15, null);
int value2 = (int)numberPropertyInfo.GetValue(calcInstance, null);
int value3 = (int)numberPropertyInfo2.GetValue(calcInstance, null);
calcType.InvokeMember("Add2",BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public,
    null, null, null);
PropertyInfo numberPropertyInfo3 = calcType.GetProperty("result");
int value4 = (int)numberPropertyInfo3.GetValue(calcInstance, null);

我只需要确切知道我必须对dll类进行哪些更改才能在此处调用它

您必须将类型的实例传递给InvokeMember

calcType.InvokeMember("Add2", flags, null, calcInstance, null);

如果要创建插件,则正确的做法是拥有三个程序集。

  1. 包含插件接口声明的类库(dll)
  2. 包含接口(插件)实现的类库(dll)
  3. 加载插件的可执行文件(exe)

接口DLL被其他两个组件引用。 您需要三个程序集,因为该插件除了其接口外,对您的应用程序一无所知,而应用程序对您的插件一无所知。 这使得插件可以互换,并且不同的应用程序可以使用相同的插件。


界面程序集Calculator.Contracts.dll

public interface ICalculator
{
    int Add(int a, int b);
}

插件实现Calculator.dll

public class Calculator : ICalculator
{
    public int Add(int a, int b)
    {
        return a + b;
    }
}

现在,您可以加载插件并在应用程序(exe)中以键入方式使用它:

Assembly asm = Assembly.LoadFrom(strDLL);
string calcInterfaceName = typeof(ICalculator).FullName;
foreach (Type type in asm.GetExportedTypes()) {
    Type interfaceType = type.GetInterface(calcInterfaceName);
    if (interfaceType != null &&
        (type.Attributes & TypeAttributes.Abstract) != TypeAttributes.Abstract) {

        ICalculator calculator = (ICalculator)Activator.CreateInstance(type);
        int result = calculator.Add(2, 7);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM