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 该实例?你应该怎么做?你应该把它作为一个输入参数吗?还是测试套件的静态 属性?
我一直在为标题中提到的概念而苦恼。我做了很多研究并找到了一些很好的例子,我试图实现其中的一些但遇到了障碍。
我最初有一个 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 方法。在我读过的许多帖子中,有两个:
我已经花了很多时间来重写所有这些函数,但我一直被困在如何实际实现被重写的 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 该实例?你应该怎么做?你应该把它作为一个输入参数吗?还是测试套件的静态 属性?