通过字符串调用实例类的方法
本文关键字:方法 实例 调用 字符串 | 更新日期: 2023-09-27 17:49:54
此链接:http://www.codeproject.com/Articles/19911/Dynamically-Invoke-A-Method-Given-Strings-with-Met清楚地解释当方法名称+类型作为字符串变量时如何调用方法。
我正在用WatiN做一个c#项目。我使用的所有WatiN方法都是相同的形式:
例子: * ( ById .ByClass…;so应该是连接的,但是我不能把它设为粗体:s)
-
browser.**TextField**(Find.By **Id**("name")).**TypeText**("my name");
-
browser.**Span**(Find.By **Class**("main_title")).**Click(**);
-
browser.**Link**(Find.By **Id**("mid_link")).**Click(**);
如你所见,它总是由3个变量方法组成。我创建了一个由字符串属性组成的类webElement:标签、类型、搜索、动作。
在示例中-> tag = "TextField"; type = "Id", search = "name"; action = "TypeText"
.
为了动态地获取web元素,我创建了一个WebHandler类,我尝试在其中动态调用正确的方法。
所以一个主类有一个所有webElement对象的列表,并且可以在给定的时间给WebHandler类正确的一个。Webhandler类现在应该动态地调用每个元素。我使用与给定url相同的调用方法,所以我调用它的代码是:
类WebHandler:
private IE browser = new IE("google.com");
public void method(WebElement webElement)
{
//Get the findBy dynamically | this works
WatiN.Core.Constraints.Constraint findBy =
(WatiN.Core.Constraints.Constraint)InvokeMethod("WatiN.Core.Find, WatiN.Core", "By" + webElement.Type, webElement.Search); //where type = "Id" and search = "name"
//Get the tag (like textfield, link, span) dynamically | this does not work
Type aType = Type.GetType("WatiN.Core." + webElement.Tag, "WatiN.Core") //how can I set the element variable to this type? aType element -> Does not work
aType element = (WatiN.Core.TextField)InvokeMethod("this.browser", webElement.Tag, findBy); //tag = TextField
element.TypeText("a name"); //same problem as above | so should be invoked
}
问题:
- 如何调用实例类IE的方法(TextField)(浏览器)动态使用他的字符串版本"TextField"作为变量?另一种表达方式是:我如何通过使用它的字符串版本"浏览器"获得当前变量(浏览器) ? 如何动态设置变量元素的类型?所以当webElement。Tag = Textfield,那么type应该是WatiN.Core.TexField元素= ..(参见代码)
自己的注意事项:
- 我发现的主要问题是,你只能从一个类型调用一个方法,所以不能从该类型的实例。有办法做到这一点吗?
这一行
Type aType = Type.GetType("WatiN.Core" + webElement.Tag)
在Core
之后没有点。看起来好像Core
是一个名称空间,因此应该与标签名称分开。
这样做的要点是您获得所需的Type,然后使用反射获得方法,然后调用给定的方法,将实例传入。
就像这样:
Type aType = Type.GetType(string.Format("WatiN.Core.{0}.WatiN.Core", webElement.Tag));
MethodInfo method = aType.GetMethod("TextField");
method.Invoke(this.browser, webElement.Tag, findBy);
这里的关键位是:
- 获取类型
- 获取方法
- 用你想要的实例调用方法
有快捷方式,我可能没有具体的细节适合你的问题,但这应该会让你接近你想要的。
好了,把这些放到了LINQPad中,但应该或多或少是可移植的:
void Main()
{
WatiN.Core.Browser theBrowser = new WatiN.Core.IE("google.com");
Foo(theBrowser, "Id", "gbqfq", "TextField", "TypeText", "Search for this");
}
public void Foo(WatiN.Core.Browser browser, string findTypeBy, string search, string tagName, string elementMethodName, params object[] argsForMethod)
{
var watinCoreAsm = Assembly.LoadWithPartialName("WatiN.Core");
if(watinCoreAsm == null) return;
var watinCoreTypes = watinCoreAsm.GetTypes();
if(watinCoreTypes == null) return;
var findType = watinCoreTypes.FirstOrDefault(type => type.Name == "Find");
if(findType == null) return;
var constraintInstance = findType.GetMethod("By" + findTypeBy, new Type[]{ typeof(string) }).Invoke(null, new[]{search});
if(constraintInstance == null) return;
var browserAccessor = browser.GetType().GetMethod(tagName, new Type[]{ constraintInstance.GetType() });
if(browserAccessor == null) return;
var resultElement = browserAccessor.Invoke(browser, new[]{ constraintInstance });
if(resultElement == null) return;
var elementMethod = resultElement.GetType().GetMethod(elementMethodName);
if(elementMethod == null) return;
elementMethod.Invoke(resultElement, argsForMethod);
}