C#通过字符串调用实例的non-static方法

C# Invoke a non-static method of an instance by string

我一直在为标题中提到的概念而苦恼。我做了很多研究并找到了一些很好的例子,我试图实现其中的一些但遇到了障碍。

我最初有一个 class 看起来像这样:

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 时,将执行静态方法并接收到 return 类型,但我不确定该方法是刚刚调用还是使用默认构造函数创建的 class 的实际实例?我开始注意到在一次调用期间设置的这个 class 的私有属性在另一次调用需要它们的不同静态函数时不存在。

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

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 
                );

但是我的class不包含那个方法。通过研究,我了解到我可以将我的 class 更改为继承自 'Type',并且我必须覆盖大约 50 个来自 'Type' 的摘要。我开始走这条路,但觉得它可能比我在这里需要做的工作更多。

我需要有一个 class 的实例,并且需要能够在 运行 时间推断出要调用哪个 non-static 方法。在我读过的许多帖子中,有两个:invoke non static method in c# 似乎将我推向了正确的方向,但我仍然缺少某些地方。

我已经花了很多时间来重写所有这些函数,但我一直被困在如何实际实现被重写的 InvokeMember 函数的问题上,我不想撤消所有这些工作来尝试在此时做其他事情.

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

我觉得你正在考虑很多关于静态、结构、反射等的假设和担忧,并且忘记了你想去的地方。你显然试图以错误的方式解决错误的问题。但我会一个一个回答你的问题。

I am not sure if the method is just called or is an actual instance of the class created using the default constructor?

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

I started noticing that private attributes of this class set during one call were not there during another call to a different static function that needed them.

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

Looking into that I learned that I could change my class to inherit from 'Type'

我看不出有任何理由需要您这样做或您认为这样做会解决什么问题。

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