2013-07-31 129 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, ...);