在泛型上使用方法

时间:2013-07-31 20:22:47

标签: c# generics unity3d

我有很多像这样的方法:

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

我想用这样的单一方法替换:

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

这显然不适用于T.Create部分。我需要做一些特定的语法吗?

我也对具有相同结果的不同方法持开放态度:单个方法接受派生的menuButton并使用正确的“item”类创建正确的方法。

4 个答案:

答案 0 :(得分:3)

不,你不能在泛型类型上调用静态方法 - 不能没有反射。除了其他任何东西,没有办法限制泛型类型具有特定的静态成员。最接近它的是无参数构造函数约束。

答案 1 :(得分: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();
    }
}

答案 2 :(得分:1)

您可以考虑使用一些界面(例如ICreator)来定义您想要调用的Create方法。

然后,您将类型参数约束为实现接口的类型(其中T:ICreator)。

然后,您将在实例上调用该方法,而不是静态方法。所以在你的情况下,也许你可以调用item.Create(...)。

对你的情况有意义吗?

答案 3 :(得分: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, ...);