【问题标题】:Run a base class method from a derived class on another assembly dynamically [duplicate]在另一个程序集上动态运行派生类的基类方法[重复]
【发布时间】:2017-05-19 21:37:55
【问题描述】:

我正在尝试使用以下代码从另一个程序集中动态地从其派生类调用基类静态方法:

Assembly executingAssembly = Assembly.GetExecutingAssembly();

Assembly objectAssembly = 
    Assembly.Load(executingAssembly.GetReferencedAssemblies().
    Where(a => a.Name == "WebDelightBLL").FirstOrDefault());

Type myType = objectAssembly.GetType("WebDelightBLL.Ingredient");

MethodInfo myMethod = myType.GetMethod("GetAll", BindingFlags.Public | BindingFlags.Static);

object myInstance = Activator.CreateInstance(myType);

dgvResultsRES.DataSource = myMethod.Invoke(myInstance, null);

DLL中的代码如下:

public class BaseClass<DerivedClass>
{
    public static Type MyType()
    {
        return typeof(DerivedClass);
    }
    public static string Prefix()
    {
        return "Sp" + MyType().Name;
    }
    public static DataTable GetAll()
    {
        try
        {
            DataTable dt = GetSP(Connection.connectionString(),
              Prefix() + "GetAll", 5);
            return dt;
        }
        catch (Exception)
        {
            throw;
        }
    }
}
public class Ingredient : BaseClass<Ingredient>
{
    public string SayHello()
    {
        return "Hello, World!"; //Just to exemplify a point
    }
}

但我总是得到“对象引用未设置为对象的实例”

例如,如果我尝试调用“SayHello()”,则不会出错。

这可能吗?

更新:

通过添加 Creep 所指示的 BindingFlags.FlattenHierarchy,它就像一个魅力。工作代码如下:

        Type myType = objectAssembly.GetType("WebDelightBLL.Ingredient");

        MethodInfo myMethod = myType.GetMethod("GetAll", BindingFlags.Public 
            | BindingFlags.Static | BindingFlags.FlattenHierarchy);

        //object myInstance = Activator.CreateInstance(myType); <-- not needed.

        dgvResultsRES.DataSource = myMethod.Invoke(null, null);

【问题讨论】:

  • 您可能想为您的问题创建一个答案,然后选择它作为您的解决方案:)
  • 如果@Creep 给出了答案,我选择它作为解决方案不是更公平吗?这是我的第一篇文章,我想尽可能对 Creep 有礼貌,省去了很多未来的麻烦......
  • 我的错 - 我没有意识到 Creep 的答案本质上是解决方案(在您的实际代码库中几乎没有调整)。所以,是的,我建议选择他的答案作为解决方案。

标签: c# .net reflection .net-assembly base-class


【解决方案1】:

由于您的方法在基类中是静态的,因此它不属于其子类。
以下代码将起作用:

Type myType = objectAssembly.GetType("WebDelightBLL.BaseClass");
MethodInfo myMethod = myType.GetMethod("GetAll", BindingFlags.Public | BindingFlags.Static);
myMethod.Invoke(null, null);

【讨论】:

  • 这里的问题是它应该从派生类中调用,以保持代码的动态性。
  • 只是猜测,但如果您在子类上工作并添加标志 | BindingFlags.FlattenHierarchy Type myType = objectAssembly.GetType("WebDelightBLL.Ingredient"); MethodInfo myMethod = myType.GetMethod("GetAll", BindingFlags.Public | BindingFlags.Static| BindingFlags.FlattenHierarchy); myMethod.Invoke(null, null);
  • 太棒了! ;) FlatterHierarchy 做到了...
【解决方案2】:

您正在尝试调用静态方法,因此您无法指定对象的实例(以摆脱“对象引用未设置为对象的实例”错误)。由于这个方法没有任何参数,你可以创建一个空的参数数组

MethodInfo myMethod = myType.GetMethod("GetAll", BindingFlags.Public | BindingFlags.Static);
// dont need this
//object myInstance = Activator.CreateInstance(myType);

//dgvResultsRES.DataSource = myMethod.Invoke(myInstance, null);
dgvResultsRES.DataSource = myMethod.Invoke(null, new object[0]);

【讨论】:

  • 没用。
猜你喜欢
  • 2012-06-23
  • 2012-08-19
  • 2021-06-03
  • 1970-01-01
  • 1970-01-01
  • 2013-05-18
  • 2018-01-18
  • 1970-01-01
相关资源
最近更新 更多