C#创建一个匿名类

时间:2018-04-02 21:34:06

标签: c# selenium

所以我的要求可能很奇怪。

假设我有一个班级CheckoutPage。我想要一个具有以下内容的“属性”Button

  • 方法Displayed()Click()
  • 带有自定义getter的属性Text
  • 私有常量locator,它是上述方法中使用的xpath

应按以下方式访问它们(checkoutPage是CheckoutPage的实例):

  • checkoutPage.Button.Click()

  • checkoutPage.Button.Displayed()

  • checkoutPage.Button.Text

实现此目的的一种方法是创建Button类并具有:

public class Button{
    const string locator = "BUTTON_LOCATOR";
    private SeleniumDriver Driver;

    public Checkout(SeleniumDriver driver){
        this.Driver = driver;
    }

    public string Text{
        get {
            return Driver.FindElement(locator).Text;
        }
    }

    public bool Displayed(){
        return Driver.FindElement(locator).Displayed;
    }

    public void Click(){
        var button = Driver.FindElement(locator);
        new Actions(Driver).Click(button).Perform();
    }
}

public class CheckoutPage{
    private SeleniumDriver Driver;
    public Button Button;

    public CheckoutPage(SeleniumDriver driver){
        this.Driver = driver;
        this.Button = new Button(Driver);
    }
}

然而,这个特定的按钮类只会使用一次,我不想让页面上的每个按钮都有一个类。那么有另一种方法可以保留CheckoutPage.Button.Something接口吗?也可以不必实例化

也许类似于:

public class CheckoutPage{
    private SeleniumDriver Driver;

    public CheckoutPage(SeleniumDriver driver){
        this.Driver = driver;
    }

    public object Button {
        const string locator = "BUTTON_LOCATOR";

        public bool Displayed(){
            return Driver.FindElement(locator).Displayed;
        }

        public void Click(){
            var button = Driver.FindElement(locator);
            new Actions(Driver).Click(button).Perform();
        }

        public string Text{
            get {
                return Driver.FindElement(locator).Text;
            }
        }
    }
}

2 个答案:

答案 0 :(得分:0)

与匿名类型的交易是它们总是在本地范围内;例如,方法不能返回匿名类型,除非将其强制转换为命名类型(例如object)。这不是非常有用,因为调用者无法访问该类型,因此您无法获得智能感知,早期绑定或类型安全。

唯一的解决方法是在调用代码中声明类型,并要求被调用的方法将其用作模板。例如,这将起作用:

public class Page
{
    public T Button<T>(T template) where T : class
    {
        return (T)Activator.CreateInstance
        (
            typeof(T), 
            new object[] 
            { 
                "Button text", 
                new Action(() => Console.WriteLine("This is a click handler")), 
                false 
            } 
        );
    }
}


public class Program
{
    static public void Main()
    {
        var template = new 
        { 
            Text = (string)null, 
            Click = (Action)null, 
            Displayed = false 
        } ;

        var page = new Page();
        var b = page.Button( template );

        Console.WriteLine(b.Text);
        Console.WriteLine(b.Displayed);
        b.Click();
    }
}

输出:

Button text
False
This is a click handler

当然,如果你传递错误的模板,它会爆炸。

老实说,我怀疑这种方法,或者这种思路,会产生一个更清晰或更清晰的解决方案,而不仅仅是声明一个具有三个属性的小类并将其返回,就像你真正应该的那样。

答案 1 :(得分:0)

我不推荐这种方法,至少你已经描述过了。页面对象模型应该向消费者呈现API ......可以在页面上完成的动作列表而不是单个元素,例如,纽扣。 LoginPage页面对象应显示Login(string username, string password)方法,而不是usernamepasswordloginButton元素。

如果您想将此描述的Button类用作页面对象中使用的内部类,那么这将更适合页面对象模型。