You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#的CheckoutPage类中实现含方法与属性的Button成员

嘿,这个需求完全可以用匿名类实现,但具体写法得看你用的编程语言——我猜你大概率是在做UI自动化(比如Selenium),常用的Java、Kotlin、C#都有对应的实现方式,下面给你逐个拆解:

先看Java的实现(最贴合需求)

Java的匿名内部类支持直接实现接口,刚好能满足你要的方法+自定义getter逻辑:

首先在CheckoutPage里定义一个Button接口,然后用匿名类实现它,同时把私有XPath常量放在外部类里(或者匿名类内部):

public class CheckoutPage {
    // 私有XPath常量,只在CheckoutPage内部可用
    private final String CHECKOUT_BUTTON_XPATH = "//button[@id='checkout-btn']";
    
    // 公开的Button成员,用匿名类实现接口
    public final Button button;

    public CheckoutPage() {
        button = new Button() {
            @Override
            public boolean displayed() {
                // 这里写判断元素是否显示的实际逻辑,比如用Selenium
                // return driver.findElement(By.xpath(CHECKOUT_BUTTON_XPATH)).isDisplayed();
                return true; // 占位示例
            }

            @Override
            public void click() {
                // 点击元素的实际逻辑
                // driver.findElement(By.xpath(CHECKOUT_BUTTON_XPATH)).click();
            }

            @Override
            public String getText() {
                // 自定义文本获取逻辑(比如处理隐藏文本、格式化等)
                // return driver.findElement(By.xpath(CHECKOUT_BUTTON_XPATH)).getText().trim();
                return "Proceed to Checkout"; // 占位示例
            }
        };
    }

    // 定义Button接口,规范方法和getter
    private interface Button {
        boolean displayed();
        void click();
        String getText();
    }
}

调用方式完全符合你的要求:

CheckoutPage checkoutPage = new CheckoutPage();
boolean isButtonShown = checkoutPage.button.displayed();
checkoutPage.button.click();
String buttonText = checkoutPage.button.getText();

Kotlin的实现(完美贴合属性需求)

Kotlin的匿名对象支持实现接口,还能直接定义带自定义getter的属性,完全满足你的所有要求:

class CheckoutPage {
    private val checkoutButtonXPath = "//button[@id='checkout-btn']"
    
    // 用匿名对象实现Button接口
    val button = object : Button {
        // 带自定义getter的Text属性
        override val text: String
            get() {
                // 自定义获取逻辑,比如格式化文本
                // return driver.findElement(By.xpath(checkoutButtonXPath)).text.trim()
                return "Proceed to Checkout"
            }

        override fun displayed(): Boolean {
            // 实际显示判断逻辑
            // return driver.findElement(By.xpath(checkoutButtonXPath)).isDisplayed
            return true
        }

        override fun click() {
            // 实际点击逻辑
            // driver.findElement(By.xpath(checkoutButtonXPath)).click()
        }
    }

    // 定义Button接口
    private interface Button {
        fun displayed(): Boolean
        fun click()
        val text: String
    }
}

调用方式完全符合预期:

val checkoutPage = CheckoutPage()
checkoutPage.button.displayed()
checkoutPage.button.click()
val buttonText = checkoutPage.button.text

C#的实现(有小限制)

C#的匿名类不能直接实现接口,而且属性只能是初始化时的固定值——如果想要自定义getter的Text属性,没法直接做到,只能用Func<string>模拟成方法调用;如果接受Text是方法而不是属性,那写法如下:

public class CheckoutPage
{
    public dynamic Button { get; }

    public CheckoutPage()
    {
        // 私有XPath常量
        string checkoutButtonXPath = "//button[@id='checkout-btn']";

        Button = new
        {
            // 实现Displayed方法
            Displayed = new Func<bool>(() =>
            {
                // 实际逻辑:return Driver.FindElement(By.XPath(checkoutButtonXPath)).Displayed;
                return true;
            }),
            // 实现Click方法
            Click = new Action(() =>
            {
                // 实际逻辑:Driver.FindElement(By.XPath(checkoutButtonXPath)).Click();
            }),
            // 用Func模拟自定义getter的Text(调用时是Text()而不是Text)
            Text = new Func<string>(() =>
            {
                // 实际逻辑:return Driver.FindElement(By.XPath(checkoutButtonXPath)).Text.Trim();
                return "Proceed to Checkout";
            })
        };
    }
}

调用时注意Text是方法:

var checkoutPage = new CheckoutPage();
bool isDisplayed = checkoutPage.Button.Displayed();
checkoutPage.Button.Click();
string buttonText = checkoutPage.Button.Text();

如果必须要Text作为属性访问(checkoutPage.Button.Text),那C#的匿名类做不到,得老老实实写命名的Button类或者用接口+实现类。

匿名类方案的优缺点

  • 优点:不用单独维护一个独立的Button类,代码更内聚,适合这个Button只在CheckoutPage里使用的场景。
  • 缺点:复用性差,如果其他页面也需要类似的Button,没法直接复用;调试时匿名类的名称不够直观;C#里对属性的支持有限。

内容的提问来源于stack exchange,提问作者Chubosaurus Rex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:43:58