2013-07-31 166 views
2

使用方法,我有一噸重的方法是這樣的:仿製藥

public T AddButton<T,K>(string name, K item, UIEventListener.VoidDelegate methodToCall, GameObject contents) where T:UIPMenuButton 
{ 
    return T.Create(name, item, methodToCall, contents); 
} 

這顯然是行不通的:

public UIPCompanyButton AddCompanyButton (string name, Company company, UIEventListener.VoidDelegate methodToCall, GameObject contents) 
{ 
    return UIPCompanyButton.Create (name, company, methodToCall, contents); 
} 

,我想用這樣一個方法,以取代在T.Create部分。我需要做某些語法嗎?

我也打開了一個不同的方法,結果相同:一個方法需要一個派生的menuButton,並用正確的「item」類創建正確的方法。

+0

在[本](http://msdn.microsoft.com/en-us/library/bb384067.aspx) – PoweredByOrange

+0

別看一看如果您覺得以下答案之一有助於您解決問題或最好地回答您的問題,請點擊左側的複選標記以接受答案。 – Steve

回答

3

不,你不能在泛型類型上調用靜態方法 - 而不是沒有反射。除了其他任何東西,都沒有辦法將泛型類型限制爲具有特定的靜態成員。最接近它的是無參數構造函數約束。

+0

更正:是的,我想發送兩個通用類型...或者理想地通過檢查第一個類的類來派生第二個類型。它似乎是因爲我的所有按鈕都有完全相同的create方法(除了「item」),並且是從相同的基類派生的,所以不需要複製粘貼數十個這些幾乎完全相同的AddItemButton方法。 – LZG

+1

@LZG:C#中沒有任何東西可以幫助您以類型安全的方式執行此操作。如果你喜歡,或者工廠,你可以使用反射 - 但是泛型不會幫助你。 –

1

你可以考慮的是有一些接口(例如ICreator),它定義了你想調用的Create方法。

然後,你會限制你的類型參數爲實現接口的類型(其中T:ICreator)。

然後你會調用一個實例的方法,而不是靜態方法。所以在你的情況下,也許你可以調用item.Create(...)。

對您的情況有什麼意義?

+0

以及問題是創建方法創建實例,所以我不能真正創建一個實例之前,我打電話給創建。如果我能得到T的類,我可以調用特定的創建方法,但我似乎無法弄清楚T是什麼類。然後,我可以將它放到一些switch語句中,比如「case T is UIPCompanyButton:」或其他。 – LZG

+0

您可以將Create方法放在公司類(或其他代碼示例中的K)中嗎?那些你已經擁有的實例。這就是我所說的item.Create。這個項目是你已經擁有的東西,當你把它作爲一個參數。 –

+0

如果你確實想要得到某個對象的類,那麼可以使用GetType()方法,但是像這樣創建一個開關並不是很面向對象,而且看起來像是一種會導致風格不良和可維護性差的事情。 –

2

你想要的是一個工廠來創建你的對象。這是一個小例子。它可能不是實現工廠模式的方式,但它應該能夠讓你繼續。請參閱this page

public class Button { 
    public string Whatever { get; set; } 

    public Button() { 
     Whatever = "Hello, world!"; 
    } 
} 

public interface IAddButton { 

    Button CreateButton(); 
} 

public class ClassToMakeButtonFor1 { 

    public static void RegisterMe() { 
     ButtonFactory.Register(typeof(ClassToMakeButtonFor1), new ButtonFactory1()); 
    } 
} 

public class ButtonFactory1 : IAddButton { 

    public Button CreateButton() { 
     return new Button(); 
    } 
} 

public class ClassToMakeButtonFor2 { 

    public static void RegisterMe() { 
     ButtonFactory.Register(typeof(ClassToMakeButtonFor2), new ButtonFactory2()); 
    } 
} 

public class ButtonFactory2 : IAddButton { 

    public Button CreateButton() { 
     var b = new Button { Whatever = "Goodbye!" }; 
     return b; 
    } 
} 

public static class ButtonFactory { 
    private static Dictionary<Type, IAddButton> FactoryMap = new Dictionary<Type, IAddButton>(); 

    public static void Register(Type type, IAddButton factoryClass) { 
     FactoryMap[type] = factoryClass; 
    } 

    public static Button MakeMeAButton<T>() where T : class { 
     return FactoryMap[typeof(T)].CreateButton(); 
    } 
} 

internal class Program { 

    private static void Main(string[] args) { 
     ClassToMakeButtonFor1.RegisterMe(); 
     ClassToMakeButtonFor2.RegisterMe(); 

     Button b = ButtonFactory.MakeMeAButton<ClassToMakeButtonFor1>(); 
     Console.WriteLine(b.Whatever); 

     b = ButtonFactory.MakeMeAButton<ClassToMakeButtonFor2>(); 
     Console.WriteLine(b.Whatever); 
     Console.ReadLine(); 
    } 
} 
0

這聽起來像你可能能夠使你的Button類通用。根據這些派生類中每個邏輯的生命有多少,這可能對您無效。

class Button<T> 
{ 
    public T Item { get; private set; } 

    public Button(string name, T item, ...) 
    { 
     // Constructor code 
    } 
} 

// Helper class for creation 
static class Button 
{ 
    public static Button<T> Create<T>(string name, T item, ...) 
    { 
     return new Button<T>(name, item, ...); 
    } 
} 

然後,使用此:

Button<Company> button = Button.Create("Name", company, ...);