2015-11-04 178 views
-2

問題標題可能不是很清楚,但這裏是我想要做的:是否有可能重載基於另一種方法的方法?

說,我有一個靜態類A。該類包含一個稱爲B的靜態函數。它有10多個重載。儘管有這麼多的過載,但這個功能非常基礎。它與該班的其他成員無關。我知道我可以在任何地方通過導入正確的名稱空間和使用訪問:

string bar = A.B("foo", true, 5) // Then do whatever with bar 

現在,假設我有另一個類C(不在A)。現在我想在C中制定一個名爲D的方法,其行爲在所有方面與A.B相同。我曾嘗試:

public static class C { 
    public static string D(string p1, bool p2, int p3) { 
     return A.B(p1, p2, p3); 
    } 
} 

但超載這個D方法一模一樣A.B,我有什麼做的?我是否必須手動編寫所有單獨的重載,還是有更好的方法?

+4

如果'C.D'「在所有方面與'A.B'表現相同,那麼C.D'有什麼用? –

+0

我知道這是毫無意義的,但僅僅是爲了知識。假設我有五個嵌套類(我不認爲會存在,但仍然)。我將不得不通過'AnIncrediblyLargeName.AnotherBigName.AnotherSubClass.YetAnotherSubClass.FinallyTheMethod'訪問它們。所以要從'C'訪問它們,我正在考慮創建一個'D'方法,以便我可以簡單地調用'D'。 –

+1

我沒有完全遵循,但是靜態方法沒有被繼承,所以沒有靜態方法的繼承或多態的機制。 –

回答

3

我將必須編寫所有單獨重載手動

如果你想擁有的DB每個重載過載,那麼,你就必須這樣做。

+0

是的,我認爲是這樣,但是D的每個重載也會與B的相應超載表現一樣。那麼即使沒有可能? –

+1

或者將所有這些方法移到一個接口/類中去接收一些編譯器援助 – Machinarius

+0

@ FarhanAnam沒有語言支持可以讓你避免它。您可以編寫自己的代碼生成工具(或查找第三方工具)爲您生成該代碼,但代碼仍然需要以某種方式編寫。 – Servy

-3

這是靜態方法缺點的一個很好的例子。

如果可以,將這些靜態方法轉換爲實例方法(可能是一些新的工作者類,使用靜態工廠方法返回實例或使用IOC)。那麼你將有更多的靈活性來使用繼承來避免重複代碼。

UPDATE

一些反饋後,我一想,它可能,一種。使用反射來獲取參數列出了B的所有版本,並與D.

public static int D(params object[] paramArray) 
{ 
    var paramTypes = paramArray.Select(x => x.GetType()); 
    var method = typeof(Static.A).GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy) 
     .Where(m => m.Name == "B" && m.GetParameters().Select(x => x.ParameterType).SequenceEqual(paramTypes)) 
     .FirstOrDefault(); 
    if (method != null) 
    { 
     return (int)method.Invoke(null, paramArray); 
    } 
    throw new Exception("Overloaded method not found"); 
} 

的參數列表進行比較這種方法的缺點是,沒有編譯時的參數檢查,沒有智能感知,等我不能想到變圓了這個的一種方式,而不重複的A.B()每個版本的規範中,像這樣:

private static int GenericD(object[] paramArray, MethodBase caller) 
    { 
     var paramTypes = caller.GetParameters().Select(x => x.ParameterType); 
     var method = typeof(Static.A).GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy) 
      .Where(m => m.Name == "B" && m.GetParameters().Select(x => x.ParameterType).SequenceEqual(paramTypes)) 
      .FirstOrDefault(); 
     if (method != null) 
     { 
      return (int)method.Invoke(null, paramArray); 
     } 
     throw new Exception("Overloaded method not found"); 
    } 

    public static int D(string p) 
    { 
     object[] paramArray = new object[] { p }; 
     return GenericD(paramArray, MethodInfo.GetCurrentMethod()); 
    } 

    public static int D(string p, int x) 
    { 
     object[] paramArray = new object[] { p, x }; 
     return GenericD(paramArray, MethodInfo.GetCurrentMethod()); 
    } 

在該溶液中,d的每一個版本()幾乎是相同的,但不相當。理想情況下,您需要某種編程方式將方法參數列表轉換爲object[],但是需要there doesn't seem to be an easy way to do that

+0

你沒有得到我害怕的問題。 –

+0

我明白你的問題是關於如何避免重複一段代碼。我指出,如果使用靜態方法/類,則避免重複自己的選項是有限的。爲什麼選擇使類A靜態或使用嵌套類有什麼特別的原因嗎? – mikeagg

+0

我無法編輯'A'。這是另一個圖書館的課程。 –

-1

爲什麼不讓你的基本方法成爲一個泛型類型的擴展方法,然後在單個擴展方法中簡單地實現任何類型特定的邏輯?

+0

爲什麼不在不知道這不是代碼優化問題的情況下回答。 –

+0

我以爲這個問題是關於如何以可重複的方式使用靜態方法。使用帶泛型的擴展方法是實現可重複技術的最簡單方法。這不是關於代碼優化,而是關於如何理解靜態,擴展和重載的基礎知識。 –

+0

好的,但是我的問題的最後兩行不是很清楚嗎? –

相關問題