C# 为什么我们必须使用as操作符来调用GetScreenshot方法

C# 为什么我们必须使用as操作符来调用GetScreenshot方法,c#,selenium-webdriver,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.

在下面的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
实现的接口方法 无需在
FirefoxDriver
对象上使用
as
操作符即可直接使用。
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接口的绑定方法是 使用公共成员实现。C#还支持显式接口 成员实现,使用它类或结构可以避免 公开成员。显式接口成员实现 使用完全限定的接口成员名称编写。对于 例如,EditBox类可以实现IControl.Paint和 使用显式接口成员的IDataBound.Bind方法 实现如下

显式接口成员只能通过接口访问 类型例如,IControl.Paint的实现由 前一个EditBox类只能通过首先转换 对IControl接口类型的EditBox引用


为什么调用
GetScreenshot
方法需要
as
操作符?

因为它在
FirefoxDriver
中实现,并由
ITakeScreenshot
接口强制执行。您已将其声明为
IWebDriver
。由于变量的类型为
IWebDriver
,因此不能对其调用
FirefoxDriver
方法。因此,他们把它投给了《意大利基督教报》

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 driver = new FirefoxDriver(); // make it a FirefoxDriver
driver.Url = "http://www.google.com";
ITakesScreenshot screenshotDriver = driver; // no cast. Not needed.
Screenshot screenShot = screenshotDriver.GetScreenshot();

只要变量声明为
FirefoxDriver
,就可以简单地使用
driver.GetScreenshot()
。。不是像现在这样的
IWebDriver

我认为面向对象编程的全部目的是为现实生活中的对象建模。以一个会打高尔夫球的人为例。无论你称呼此人为“父亲”或“先生”或“首席执行官”,这取决于他的职业/社会角色,他不会突然失去打高尔夫球的能力。这也是OOP中应该采用的方式。我们不应该叫这个人“高尔夫球手”来获得他的高尔夫能力。如果高尔夫球手也是某个人的“父亲”,我们应该能够称他为“父亲”,并且仍然可以了解他的高尔夫能力。我想你会发现很难找到引用“模型现实对象”的资源。这只是一种基本上为对象建模的方法。它没有“真实生活”。如果从OO中删除与“真实生活”的关联,将有助于您理解OO。在两种方式中,我们都调用FirefoxDriver构造函数,但只有一种方式我们能够访问此类中的所有方法。我不知道,我觉得这有点像骗局。假装我们在创建同一个对象时创建了更大对象的子集。几乎不诚实。
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();