为什么我们必须使用as运算符来调用GetScreenshot方法

时间:2013-12-31 00:49:29

标签: c# selenium-webdriver

在下面的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方法?

1 个答案:

答案 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