簡體   English   中英

模擬枚舉繼承:最佳選擇和實踐

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM