如何动态决定使用哪个静态类

时间:2017-11-02 18:00:20

标签: c# oop

我们有一个包含一堆作为静态字符串存储的css选择器的大类。例如:

public class Constants
}
    public static string Selector1 = "#someID";
    public static string Selector2 = ".some.classes a";
    // and so on...
}

我们现在需要测试我们的网络应用程序的不同版本,这需要一些不同的选择器。因此,我们需要找到一种干净的可扩展方式来根据某些配置覆盖这些选择器。

我对此问题的解决方案是:我正在尝试创建一个BaseConstants类,它将具有当前的选择器集。然后我创建另一个名为UpdatedConstants的类,它将继承BaseConstants类。然后,此类将对所有选择器进行控制,并覆盖需要使用new关键字进行更改的选择器。例如:

public class UpdatedConstants : BaseConstants
{
    // Overrides the base class's Selector1 string
    public new static string Selector1 = "#someOtherID";
}

这适用于覆盖字符串但是我很难理解项目在编译时将如何决定使用哪个静态类。我们现有的所有代码都使用Constants类,如下所示:
var element = driver.GetElement(Constants.SomeSelector);

有没有办法动态决定哪个类是最后的Constants类?也许是通过一些元编程魔术?

让我知道是否有人有问题或需要更好地解释问题。感谢

3 个答案:

答案 0 :(得分:2)

使常量类非静态并使用单例。这也允许您使用虚拟属性,因为您要使用基本Constants类。

public static class Constants
{
    static Constants()
    {
#if FOO
        Current = new ConstantsFoo();
#elif BAR
        Current = new ConstantsBar();
#endif
    }

    public static ConstantsBase Current { get; private set; }
}

//...snip

var element = driver.GetElement(Constants.Current.SomeSelector);

答案 1 :(得分:0)

如果您不想更改所有出现Constants.SomeSelector,那么拥有不同行为的唯一方法是使用Constants类中的预处理器指令:

public class Constants
}
#if OLD
    public static string Selector1 = "#someID";
#elif NEW
    public static string Selector1 = "#someNewID";
#endif
    public static string Selector2 = ".some.classes a";
    // and so on...
}

否则你可以使用Ed Plunketts的方法回答。

答案 2 :(得分:0)

好吧,可能不是你要找的东西,但是......你可能想要考虑这样做。

这样说吧 - 如果你走在路上,5年后你的代码会是什么样子?您将拥有一个包含原始设置的基类,第一次(当您提出此问题时)修改它们的子类,继承自 子类的子类如何下次修改,依此类推。我可以很容易地想象一个巨型链中的10个子类 - 如果你想跟踪任何设置的当前值,你必须向上移动该链,直到找到它最近设置/覆盖的位置。说实话,这听起来像是一场维护噩梦。

如果我在你的鞋子里,这就是新代码的样子:

public static class Constants
{
    public static string Selector1 { get { return ReadFromSettings("Selector1"); } }
    public static string Selector2 { get { return ReadFromSettings("Selector2"); } }
    //etc
    // then, code for ReadFromSettings()
}

...然后将这些设置迁移到实际设置文件中。没有人需要更改调用端的任何代码(它们仍然引用Constants.Selector1) - 除了在一系列派生类中使用所有硬编码之外,您只需要一个包含值的文件。