C#中实现显式转换时出现强制转换异常

3

我有一个外部函数:

public int SetHeight(IWebElement column)
{
    ExtendedElement.Get(column).Click();
}

在调用中接收到的column参数已经是具体类型ExtendedElement,但由于它接受任何IWebElement,我需要那个Get方法。

这里是ExtendedElement的重要部分:

public class ExtendedElement : IWebElement
{
    private IWebElement _Element { get; set; }
    private ExtendedElement() {}

    public static ExtendedElement Get(IWebElement element)
    {
        return new ExtendedElement()
        {
            _Element = (RemoteWebElement)element
        };
    }

    public static explicit operator RemoteWebElement(ExtendedElement element)
    {
        return (RemoteWebElement)element._Element;
    }
    // other impmlementations
}

如何编写从Microsoft读取的转换?

但是由于某些原因,当运行代码时,我会收到异常: System.InvalidCastException:无法将类型为“Core.Helper.ExtendedElement”的对象强制转换为类型“OpenQA.Selenium.Remote.RemoteWebElement”。

那么,为什么会这样呢?如果我过于复杂并需要更改设计 - 应该怎么做?


你可能是想说 _Element 的类型应该是 RemoteWebElement 而不是 IWebElement - Evk
@Evk,无论哪种方式都不起作用。 - ephemeris
1个回答

1
要实现一个定制的网络元素并保留其原始方法,请扩展RemoteWebElement
public class ExtendedElement : RemoteWebElement
{

    public static ExtendedElement Get(IWebElement element)
    {
        RemoteWebDriver driver = (RemoteWebDriver)element.WrappedDriver;
        string id = (string)typeof(RemoteWebElement)
                        .GetProperty("Id", BindingFlags.NonPublic | BindingFlags.Instance)
                        .GetValue(element, null);

        return new ExtendedElement(driver, id);
    }

    public ExtendedElement(RemoteWebDriver driver, string id)
        : base(driver, id)
    { }

}

无法访问 IWebElementReference 中的 ((IWebElementReference)element),因为它是内部的,不能调用 element.Id。错误提示为 Cannot access protected member 'RemoteWebElement.Id' via a qualifier of type 'RemoteWebElement'; the qualifier must be of type 'ExtendedElement' (or derived from it) - ephemeris
我错过了那个。一个解决方法是使用反射来获取id。另一种方法是调用 string id = element.ToString(); id = id.Substring(14, id.Length - 15);。你应该为缺乏可扩展性而打开一个工单。 - Florent B.
尝试使用反射,但出现了空引用异常:base((RemoteWebDriver)element.WrappedDriver, (string)element.GetType().GetProperty("Id", BindingFlags.NonPublic).GetValue(element, null))请问您能否更新答案,使用正确的反射用法? - ephemeris
更新:使用以下代码成功运行:(string)element.GetType().GetProperty("Id",BindingFlags.NonPublic | BindingFlags.Instance).GetValue(element,null))。请更新答案,以便我可以接受它。谢谢!我自己再过一个月也想不出来这个方法。 - ephemeris
你尝试过直接使用 element.ToString(); 获取id吗?我认为这样会更简洁。 - Florent B.
1
这似乎已经起作用了:base((RemoteWebDriver)element.WrappedDriver, element.ToString().Substring(14, element.ToString().Length - 15))。将其制作成一个语句以保持相同的构造函数。不确定是否更清晰,如果框架开发人员更改了 ToString 的输出格式会怎样?至少通过反射,我可以得到我要求的内容或 null,并且如果失败,我会立即注意到。此外,我不确定从 ExtendedElement 对象中获取的 Id 是否实际上被调用到我的测试中的任何地方。 - ephemeris

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接