【问题标题】:C# Invoke a non-static method of an instance by string [closed]C#通过字符串调用实例的非静态方法[关闭]
【发布时间】:2021-07-09 18:55:20
【问题描述】:

我一直在为标题中提到的概念而苦苦挣扎。我进行了大量研究并找到了一些很好的例子,我尝试实施其中一些,但遇到了障碍。

我最初的课程是这样的:

namespace sysVer
{
    public class testSuite
    {
        /* there is a bunch of test hardware setup
         * and acquisition also that is not shown
         */
        public struct testResultInfo
        {
            public testStatus testStat;
            public bool warning, error;
            public string warnStr, errStr, infoStr, muxDataStr;
            public double measDecVal;
            public Int16 measIntVal;
        };
        
        // NOTE there is no default constructor
        
        public static testResultInfo testCase1()
        {
            
        }
        public static testResultInfo testCase2()
        {
            
        }
        public static testResultInfo testCase3()
        {
            
        }
        // there are about 100 more
    }
}

使用带有 105 个复选框和字典的 windows 窗体来确定用户想要运行哪个函数,我能够使用 Invoke Member 通过字符串调用函数,如下所示:

// first attempt
namespace sysVer
{
    public partial class SysVerForm : Form
    {
        public static Pdgu1553ver.testResultInfo tcResult = new Pdgu1553ver.testResultInfo ( )
        {
            testStat = Pdgu1553ver.testStatus.pass,
            warning = true,
            error = true,
            warnStr = "This is a warning",
            errStr = "This is an error",
            infoStr = "This is info",
            muxDataStr = "Mux data of some sort",
            measDecVal = 69.69,
            measIntVal = 69
        };
        
        // for loop that iterates over checkbox checked items
        foreach ( var checkedItem in checkedItems )
        {
            var funcName = "";
            
            // retrieve function name from dictionary
            tcToFuncDic.TryGetValue ( checkedItem.ToString ( ), out funcName );
            
            tcResult = ( testSuite.testResultInfo ) typeof ( testSuite ).InvokeMember 
                (
                    funcName,
                    BindingFlags.InvokeMethod |
                    BindingFlags.Public |
                    BindingFlags.Static,
                    null,
                    null,
                    null 
                );
        }
    }
}

但是我在这里遇到了问题。当调用 InvokeMember 时,会执行静态方法并接收到返回类型,但我不确定该方法是刚刚调用还是使用默认构造函数创建的类的实际实例?我开始注意到,在一次调用期间设置的此类的私有属性在另一次调用需要它们的不同静态函数时不存在。

我假设我需要我的类的一个实例,所以我更改为以下内容:

namespace sysVer
{
    public class testSuite
    {
        /* there is a bunch of test hardware setup
         * and acquisition also that is not shown
         */
        public struct testResultInfo
        {
            public testStatus testStat;
            public bool warning, error;
            public string warnStr, errStr, infoStr, muxDataStr;
            public double measDecVal;
            public Int16 measIntVal;
        };
        
        // constructor
        public testSuite()
        {
            /* Here I initialize hardware, set variables, and
             * run a few other tasks.  All of which need to be done
             * an exist before this object can be used
             */
        }
        
        public testResultInfo testCase1()
        {
            
        }
        public testResultInfo testCase2()
        {
            
        }
        public testResultInfo testCase3()
        {
            
        }
        //... there are about 100 more
    }
}

现在,我撞到了另一面墙。我需要做这样的事情:

testSuite myTest = new testSuite();
var blah = myTest.InvokeMember(
                    funcName,
                    BindingFlags.InvokeMethod |
                    BindingFlags.Public |
                    BindingFlags.Static,
                    null,
                    null,
                    null 
                );

但我的课程不包含该方法。调查后我了解到我可以将我的类更改为从“Type”继承,并且我必须从“Type”中覆盖大约 50 个左右的抽象。我开始走这条路,但觉得这可能比我需要做的工作要多。

我需要我的类的一个实例,并且需要能够在运行时推断出要调用哪个非静态方法。在我读过的许多帖子中,这两个:How to invoke a non static method by reflectioninvoke non static method in c# 似乎将我推向了正确的方向,但我仍然在某个地方遗漏了一些东西。

我已经花了很多时间来覆盖所有这些函数,但我却被困在那里如何实际实现被覆盖的 InvokeMember 函数,我不想在此时撤消所有工作以尝试做其他事情。

一如既往,非常感谢任何建议。感谢您的时间和考虑。

【问题讨论】:

  • Looking into that I learned that I could change my class to inherit from 'Type' - 我很想知道你是怎么学会的。不,您不是从 Type 继承的。您获取类型,从中获取方法信息,然后Invokevery answer you are linking to 中明确列出了类似的方法信息。
  • 你的问题很不清楚。你似乎已经尝试了很多不同的东西,这些东西可能与你想要的不同。当然,继承Type 是完全错误的。在几乎每一种情况下,如果你想调用一个非静态方法,它应该是only,因为你已经有一个相关的对象instance来调用该方法,在那种情况下,我们已经在这里拥有的许多“通过反射调用方法”问答中的任何一个都足够了。请edit your question改进。删除所有不必要的...
  • ... 信息(这似乎是您在上面发布的大部分内容),同时确保包含一个minimal reproducible example,显示您获得的最接近成功的信息,以及清晰的解释该代码的作用、您想要什么以及具体您需要什么帮助。
  • @GSerg,这是我第一次搞砸这些东西,但在 link Type Class 网站上的“实施者须知”部分下,它声明“当你从 Type 继承时,你必须重写以下成员:',所以我想我需要继承它。也许那是个错误
  • @MichaelRiley 这些是给实现者的注释。你不是一个。您可以在许多类上找到此类注释,无需自己实现即可使用。

标签: c# instance system.reflection non-static invokemember


【解决方案1】:

我感觉到您正在将大量假设和问题与静态、结构、反射等复杂化,并且不知道您想去哪里。您显然试图以错误的方式解决错误的问题。但我会一次解决一个问题。

我不确定该方法是刚刚调用还是使用默认构造函数创建的类的实际实例?

你为什么会这样想?您没有发布测试方法的代码,但我可以向您保证 InvokeMember 实际上调用了该成员

我开始注意到,在一次调用期间设置的此类的私有属性在另一次调用需要它们的不同静态函数时不存在。

可能是因为测试方法每次都会创建一个新的testResultInfo,但是没有代码就不可能知道。但我不明白为什么这是一个问题。您需要“结转”哪些数据?也许您需要 testSuite 上的静态 testResultInfo 属性,您可以在方法中重用它?

调查后我了解到我可以将我的类更改为从“类型”继承

我看不出有什么理由你需要这样做,或者你认为这会解决什么问题。

停止尝试通过尝试解决其他问题(可能以错误的方式)产生的顶级创可贴问题。备份、分析您的程序并考虑创建不同实例的位置?这些测试方法应该神奇地知道您在表单中创建的实例,还是应该以某种方式给定该实例?你应该怎么做?你应该把它作为输入参数吗?还是测试套件的静态属性?

【讨论】:

  • 这不是浪费——我们不是花了几个小时试图解决所有问题——我的目的更多的是鼓励你退后一步,回归基础,而不是试图解决错误的问题.如果您仍有具体问题,请不要害怕提问。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-28
  • 1970-01-01
  • 1970-01-01
  • 2020-11-04
相关资源
最近更新 更多