模拟枚举inheritance:最佳选择和实践

我正在设计一个测试应用程序(使用NUnit),它必须通过网页导航(通过Selenium Webdriver API)。 我想使用枚举来模拟站点结构,以便能够通过此枚举告诉方法导航的位置(尤其是NUnit方法)。

this.NavigateTo(Page.HomePage); 

这是一个强烈的要求(在某处有一个枚举类型),主要是因为NUnit不能传递非基本类型。 例如,NUnit不可能使用这种语法,因为Page 必须是原始的或枚举的:

 static class Page{ public static Page HomePage; public static Page UserAccountPage; } /* ... later ... */ [TestCase(Page.HomePage)] void TestMethod(Page p) { ... 

我也想使用相同的enum-or-like来制作基本的inheritance,比如

 interface IPage{} interface IPageNavigatable : Page {} interface IPageUserRelated : Page {} interface IWildcardPage : Page {} enum Page{ HomePage : IPageNavigatable, UserAccountPage : IPageNavigatable IPageUserRelated, ErrorPage : /* none */, AnyPage : IWildcardPage } 

然后,我将能够制作非常有趣的方法

 bool IsCurrentPage(IWildcardPage p); void LoginThenNavigate(String user, String pw, IPageUserRelated p); Page WhereAmI(); /* and use this value with IsAssignableFrom */ 

我知道C#禁止枚举inheritance(我仍然不明白这个选择,但现在这不是我的问题)而且我已经阅读了一些解决方法,包括一个从头开始重构 enum机制的类; 没有人看起来令人满意

我所拥有的最好的想法是使用一个内部枚举和一些公共布尔值的复杂类。 不太满意……

 public class Page{ enum Pages { /* you know them */} public Page.Pages InnerPage; public bool isWildcard, isUserRelated, ...; public Page(Page.Pages p){ this.InnerPage = p; switch (p){ case ...: case ...: this.isWildcard = true; break; /* ... */ } } } /* NUnit calls */ [TestCase(Page.Pages.HomePage)] void TestMethod(Page.Pages p) { ... 

此外,在一个完美的世界中,我喜欢用字符串或URI“链接”我的枚举或类型值,以便我可以编写如下内容:

 enum Page{ HomePage : IPageNavigatable = "/index.php", UserAccountPage : IPageNavigatable IPageUserRelated = "/user.php", ErrorPage : /* none */ = (String) null, AnyPage : IWildcardPage = (String) null } /* ... */ Page p; Selenium.Webdriver drv; drv.Navigate().GoToUrl(new Url(p.ToString())); 

这对我来说是一个棘手的问题。 有人可以帮忙吗?

编辑:克里斯在下面指出的一个线索是,NUnit(通过属性)可以采用Object类型的参数。 使用它,可能有一种方法用我的inheritance结构实现几乎没有代码的对象,并重新编码枚举机制的一部分(并链接到URL字符串)。

不是我的梦想解决方案,但可能有效

你确定它们必须是原始的(顺便说一句,我们称之为.net世界中的那些值类型或结构)? 这个页面似乎意味着你受限制的原因是因为.NET属性的固有限制,这反过来在这里描述:

属性参数限制为以下类型的常量值:

简单类型(bool,byte,char,short,int,long,float和double)

系统类型

枚举

object(对象类型的属性参数的参数必须是上述类型之一的常量值。)

任何上述类型的一维arrays

这告诉我以下内容可行:

 static class Pages { public const String HomePage = "Home Page"; public const String UserAccountPage = "User Account Page"; } [TestCase(Pages.HomePage)] void TestMethod(Page p) { ... 

您是否尝试过只使用自定义类而不是枚举?

 public class Page { public IPageNavigatable HomePage = "/index.php"; public IPageNavigatable UserAccountPage = "/user.php"; public Type ErrorPage = null; public IWildcardPage AnyPage = null; }