簡體   English   中英

通過字符串調用實例類的方法

[英]Invoke Method of instance class through string

此鏈接: http : //www.codeproject.com/Articles/19911/Dynamically-Invoke-A-Method-Given-Strings-with-Met清楚地說明了當您使用方法名稱+類型作為字符串變量時如何調用方法。

我正在與WatiN進行ac#項目。 我使用的所有WatiN方法都具有相同的形式:

示例: *( ById,.ByClass ..;因此應該被連接,但是后來我無法將其設置為粗體: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" tag = "TextField"; type = "Id", search = "name"; action = "TypeText" tag = "TextField"; type = "Id", search = "name"; action = "TypeText"

為了動態獲取Web元素,我創建了一個WebHandler類,在其中嘗試動態調用正確的方法。

因此,主類具有所有webElement對象的列表,並且可以在給定的時間向WebHandler類提供正確的對象。 Webhandler類現在應該動態調用每個元素。 我使用與給定url中相同的invoke方法,因此調用它的代碼是:

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
}

問題:

  1. 如何使用其字符串版本“ TextField”作為變量動態調用實例類IE( 瀏覽器 )的方法( TextField )? 措辭的另一種方式是:如何通過使用其字符串版本“瀏覽器”來獲取當前變量( 瀏覽器 )?
  2. 如何動態設置變量元素的類型? 因此,當webElement.Tag = Textfield時,類型應為WatiN.Core.TexField element = ..(請參見代碼)

自己的注意事項:

  1. 我發現的主要問題是,您只能從類型調用方法,而不能從該類型的實例調用方法。 反正有辦法嗎?

這條線

Type aType = Type.GetType("WatiN.Core" + webElement.Tag)

Core之后沒有點。 似乎Core是一個命名空間,因此應該與Tag名稱分開。

要點是,您將獲得所需的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);

這里的關鍵位是:

  1. 獲取類型
  2. 獲取方法
  3. 用您想要的實例調用方法

有捷徑,而且我可能沒有針對您問題的詳細信息,但這應該使您接近所需的內容。

可以,將它們放在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);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM