C# Appium/Selenium 派生 WindowsElement 在转换时抛出错误
C# Appium/Selenium Derive WindowsElement throws error on cast
在我的 C# .NET Framework 4.8 项目中,我试图派生 WindowsElement class 以在新的 class 中实现一些附加功能。
例如 ClickInMiddleOfControl、IsVisible 或 SelectedItem(在 ComboBox 中)。
public class WindowsElementWrapper : WindowsElement
{
public WindowsElementWrapper(RemoteWebDriver parent, string id) : base(parent, id) { }
public void ClickInMiddleOfControl()
{
var rect = this.Rect;
var offsetx = (int)(0.5 * rect.Width);
var offsety = (int)(0.5 * rect.Height);
new Actions(Helper.Session)
.MoveToElement(this, 0, 0)
.MoveByOffset(offsetx, offsety)
.Click()
.Build()
.Perform();
}
}
然后我尝试将 WindowsElement 投射到我的 WindowsElementWrapper。
var element = (WindowsElementWrapper)Session.FindElementByName("ElementName");
element.ClickInMiddleOfControl();
但是在运行时我收到以下错误消息:
System.InvalidCastException: 'Unable to cast object of type
OpenQA.Selenium.Appium.Windows.WindowsElement' to type
'WEW.WindowsElementWrapper'.'
是否无法从 WindowsElement 派生class?还是我犯了根本性错误?
从 WindowsElement
到 WindowsElementWrapper
的转换是 downcast。
为了使向下转型成功,对象的运行时类型必须是目标类型本身,或者是从它派生的类型。
尽管 WindowsElementWrapper
是 WindowsElement
,但 WindowsElement
不一定是 WindowsElementWrapper
。
换句话说,这种向下转换永远不会成功,除非 SeleniumAPI 实例化 对象作为 WindowsElementWrapper
开始。
为了实现你想做的事情,你可以应用以下设计之一:
Composition
public class WindowsElementWrapper
{
private readonly WindowsElement element;
public WindowsElementWrapper(WindowsElement element, (int Width, int Height) rect)
{
this.element = element;
Rect = rect;
}
public (int Width, int Height) Rect { get; init; }
public void ClickInMiddleOfControl()
=> new Actions(Helper.Session)
.MoveToElement(element, 0, 0)
.MoveByOffset(Rect.Width / 2, Rect.Height / 2)
.Click()
.Build()
.Perform();
}
Extension methods
public static class Extensions
{
public static void ClickInMiddleOfControl(this WindowsElement source, (int Width, int Height) rect)
=> new Actions(Helper.Session)
.MoveToElement(source, 0, 0)
.MoveByOffset(rect.Width / 2, rect.Height / 2)
.Click()
.Build()
.Perform();
}
此致
在我的 C# .NET Framework 4.8 项目中,我试图派生 WindowsElement class 以在新的 class 中实现一些附加功能。 例如 ClickInMiddleOfControl、IsVisible 或 SelectedItem(在 ComboBox 中)。
public class WindowsElementWrapper : WindowsElement
{
public WindowsElementWrapper(RemoteWebDriver parent, string id) : base(parent, id) { }
public void ClickInMiddleOfControl()
{
var rect = this.Rect;
var offsetx = (int)(0.5 * rect.Width);
var offsety = (int)(0.5 * rect.Height);
new Actions(Helper.Session)
.MoveToElement(this, 0, 0)
.MoveByOffset(offsetx, offsety)
.Click()
.Build()
.Perform();
}
}
然后我尝试将 WindowsElement 投射到我的 WindowsElementWrapper。
var element = (WindowsElementWrapper)Session.FindElementByName("ElementName");
element.ClickInMiddleOfControl();
但是在运行时我收到以下错误消息:
System.InvalidCastException: 'Unable to cast object of type OpenQA.Selenium.Appium.Windows.WindowsElement' to type 'WEW.WindowsElementWrapper'.'
是否无法从 WindowsElement 派生class?还是我犯了根本性错误?
从 WindowsElement
到 WindowsElementWrapper
的转换是 downcast。
为了使向下转型成功,对象的运行时类型必须是目标类型本身,或者是从它派生的类型。
尽管 WindowsElementWrapper
是 WindowsElement
,但 WindowsElement
不一定是 WindowsElementWrapper
。
换句话说,这种向下转换永远不会成功,除非 SeleniumAPI 实例化 对象作为 WindowsElementWrapper
开始。
为了实现你想做的事情,你可以应用以下设计之一:
Composition
public class WindowsElementWrapper
{
private readonly WindowsElement element;
public WindowsElementWrapper(WindowsElement element, (int Width, int Height) rect)
{
this.element = element;
Rect = rect;
}
public (int Width, int Height) Rect { get; init; }
public void ClickInMiddleOfControl()
=> new Actions(Helper.Session)
.MoveToElement(element, 0, 0)
.MoveByOffset(Rect.Width / 2, Rect.Height / 2)
.Click()
.Build()
.Perform();
}
Extension methods
public static class Extensions
{
public static void ClickInMiddleOfControl(this WindowsElement source, (int Width, int Height) rect)
=> new Actions(Helper.Session)
.MoveToElement(source, 0, 0)
.MoveByOffset(rect.Width / 2, rect.Height / 2)
.Click()
.Build()
.Perform();
}
此致