在下面的C#代码中,我们使用Firefox webdriver截取屏幕截图,为什么我们必须使用as运算符来调用GetScreenshot
方法?
IWebDriver driver = new FirefoxDriver();
driver.Url = "http://www.google.com";
ITakesScreenshot screenshotDriver = driver as ITakesScreenshot;
Screenshot screenShot = screenshotDriver.GetScreenshot();
screenShot.SaveAsFile(
screenshotFileName,
System.Drawing.Imaging.ImageFormat.Png);
FirefoxDriver
继承RemoteWebDriver
类并实现ITakesScreenshot
接口。可以调用RemoteWebDriver
实现的接口方法
直接而无需在as
个对象上使用FirefoxDriver
运算符。 GetScreenshot
方法在FirefoxDriver.cs中实现,如下所示:
public class FirefoxDriver : RemoteWebDriver, ITakesScreenshot
{
//...
public Screenshot GetScreenshot()
{
// Get the screenshot as base64.
Response screenshotResponse = Execute(DriverCommand.Screenshot, null);
string base64 = screenshotResponse.Value.ToString();
// ... and convert it.
return new Screenshot(base64);
}
}
我们不应该简单地将此方法称为driver.GetScreenshot()
吗?
C#语言规范文档规定显式接口成员只能通过接口类型访问,但我不知道这对GetScreenshot
方法有何影响。
在上一个EditBox类中,来自IControl的Paint方法 接口和IDataBound接口的Bind方法是 使用公共成员实施。 C#还支持显式接口 成员实现,类或结构可以使用它来避免 使成员公开。显式接口成员实现 使用完全限定的接口成员名称编写。对于 例如,EditBox类可以实现IControl.Paint和 IDataBound.Bind方法使用显式接口成员 实现如下。
public class EditBox : IControl, IDataBound
{
void IControl.Paint() {...}
void IDataBound.Bind(Binder b) {...}
}
只能通过界面访问显式接口成员 类型。例如,IControl.Paint的实现由 以前的EditBox类只能通过首先转换来调用 EditBox对IControl接口类型的引用。
EditBox editBox = new EditBox();
editBox.Paint(); // Error, no such method
IControl control = editBox;
control.Paint();
为什么我们需要as
运算符才能调用GetScreenshot
方法?
答案 0 :(得分:4)
因为它在FirefoxDriver
中实现并由ITakeScreenshot
接口强制执行。您已将其声明为IWebDriver
。由于您的变量属于IWebDriver
类型,因此无法在其上调用FirefoxDriver
方法。因此,他们将其投放到ITakeScreenshot
。
要做你想做的事......你可以这样做:
FirefoxDriver driver = new FirefoxDriver(); // make it a FirefoxDriver
driver.Url = "http://www.google.com";
ITakesScreenshot screenshotDriver = driver; // no cast. Not needed.
Screenshot screenShot = screenshotDriver.GetScreenshot();
只要您的变量声明为driver.GetScreenshot()
而不是FirefoxDriver
,就可以使用IWebDriver
。