[英]Emulate enum inheritance: best choice & practices
我正在設計一個測試應用程序(使用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) { ...
我也想使用相同的枚舉或類似枚舉進行基本繼承,例如
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#禁止枚舉繼承(我還是不明白,這樣的選擇,但現在這不是我的問題),我讀過一些解決方法,包括從頭枚舉機制重新編碼的一類; 而且看起來都不令人滿意。
我最好的主意是使用帶有內部枚舉和一些公共布爾值的復雜類。 不太滿意...
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類型的參數。 使用此方法,可能有一種方法可以用我的繼承結構實現幾乎沒有代碼的對象,並重新編碼枚舉機制的一部分(並鏈接到URL字符串)。
不是我的理想解決方案,但可能會起作用...
您是否嘗試過僅執行自定義類而不是枚舉?
如
public class Page
{
public IPageNavigatable HomePage = "/index.php";
public IPageNavigatable UserAccountPage = "/user.php";
public Type ErrorPage = null;
public IWildcardPage AnyPage = null;
}
您確定它們必須是原語嗎(順便說一下,我們在.net世界中稱為“值類型”或“結構”)? 該頁面似乎暗示您受到限制的原因是由於.NET屬性的固有限制,因此在此進行了描述:
屬性參數限制為以下類型的常量值:
簡單類型(bool,byte,char,short,int,long,float和double)
串
系統類型
枚舉
對象(類型為對象的屬性參數的參數必須為上述類型之一的常數。)
以上任何類型的一維數組
這向我暗示以下方法會起作用:
static class Pages {
public const String HomePage = "Home Page";
public const String UserAccountPage = "User Account Page";
}
[TestCase(Pages.HomePage)]
void TestMethod(Page p) { ...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.