反射调用的C#方法无法访问公共静态成员的数据



我有三个类。第一个public static class DataContainer、第二个public class DoInvocations和第三个public class Execute(注意:为了更容易理解,这些只是示例名称)DoInvocationsDataContainer获得关于类Execute的某些汇编信息。为了能够从这个类中调用一个方法。

因此,在我获得程序集信息后,请求的方法在类DoInvocations中被成功调用。

invokeInformation.InvokeMember(
DataContainer.MethodName,
BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.Public,
null, null, inputParamList);

MethodName是来自DataContainerpublic static string prop{ get; private set; },因此它应该可用于所有其他类。


现在在Execute类中,被调用的方法不能访问DataContainer类的public static成员。如果我想访问它们,它们的所有值都是null

public class Execute
{
public static void DoSomething() //DoSomething is the earlier DataContainer.MethodName
{
string whatEver = DataContainer.MethodName;
}
}

CCD_ 15原来是CCD_。当我再次调用该方法时(没有将任何信息重新加载到DataContainer),调用再次成功。所以这些信息并没有消失。在invoke方法之后,类Execute似乎访问了DataContainer的一个空实例,但因为该类是static,所以已经不可能创建它的实例了。我真的不知道我的代码中发生了什么。

我已经在MethodName道具上设置了一个断点,但从未更改。我做错了什么?

这是一个最小、完整且可验证的示例,说明您所说的正在做的事情。它的作用正如人们所期望的那样。因此,您需要弄清楚您所做的其他操作会导致应用程序失败。

namespace ConsoleApp3
{
using System;
using System.Reflection;
public static class DataContainer
{
public static string MethodName { get; set; }
}
public class DoInvocations
{
public void Method()
{
typeof(Execute).InvokeMember(
DataContainer.MethodName,
BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.Public,
null, null, null);
}
}
public class Execute
{
public static void DoSomething()
{
Console.WriteLine(DataContainer.MethodName);
}
}
class Program
{
static void Main()
{
DataContainer.MethodName = "DoSomething";
new DoInvocations().Method();
Console.ReadLine();
}
}
}

当其他人遇到同样的问题时,他们做错了一些事情:有些人认为static是全局性的,无论DLL加载到哪里。事实并非如此。每次加载库时,它都会获得自己的内存。所以,确保你所做的每件事都在同一个过程中。

一般来说,即使在同一进程中,拥有静态属性也不是在实例之间进行通信的好方法。这就是方法参数的作用。也许你可以找到一种方法,将你的方法名称传递给需要它的方法,这很可能会让你的问题消失。

问题是我加载了错误的程序集。因为我直接从文件路径加载程序集:

Assembly TestAssembly = Assembly.LoadFrom("...\somePath.dll");

问题是这个程序集没有初始化,这就是为什么属性DataContainer.MethodName总是返回值null的原因。

因此,我只需以这种方式加载所需.dll的程序集,即可获得当前初始化的程序集。

Assembly TestAssembly = typeof(DataContainer).Assembly;

由于属性DataContainer.MethodName当时已经初始化,并且我没有加载未初始化的.dll,所以它返回了预期值,而不是null,调用成功。

Type invokeInformation = TestAssembly.GetType(...);
invokeInformation.InvokeMember(
DataContainer.MethodName,
...);

相关内容

  • 没有找到相关文章

最新更新