简体   繁体   English

在泛型上使用方法

[英]Using methods on Generics

I have a ton of methods like this: 我有很多这样的方法:

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

that I'd like to replace with a single method like this: 我想用这样的单个方法替换:

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

which obviously doesn't work at the T.Create part. 这显然在T.Create部分不起作用。 Is there a certain syntax I need to do this? 我需要执行某种语法吗?

I'm also open to a different method with the same result: a single method that takes in a derived menuButton and creates the right one with the right class of "item". 我也对具有相同结果的其他方法持开放态度:一种方法采用一个派生的menuButton并使用正确的“ item”类创建正确的方法。

No, you can't call static methods on generic types - not without reflection. 不,您不能在泛型类型上调用静态方法-不能没有反射。 Aside from anything else, there's no way of constraining a generic type to have specific static members. 除了其他方面,没有任何方法可以限制泛型具有特定的静态成员。 The closest to that is the parameterless constructor constraint. 最接近该参数的是无参数构造函数约束。

What you want is a factory to create your objects. 您想要的是创建对象的工厂。 Here is a small working example. 这是一个小的工作示例。 It might not be the best way to implement a factory pattern, but it should get you going. 它可能不是实现工厂模式的最佳方法,但是它应该可以帮助您。

For a more in depth example and explanation, see 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();
    }
}

What you could consider is to have some interface (eg ICreator) that defines a Create method you want to call. 您可以考虑使用一些接口(例如ICreator)来定义要调用的Create方法。

Then you would constrain your type parameter to types that implement the interface ( where T : ICreator). 然后,将类型参数约束为实现接口的类型(其中T:ICreator)。

Then you would call the method on an instance, not a static method. 然后,您将在实例上调用该方法,而不是静态方法。 So in your case maybe you could call item.Create(...). 因此,在您的情况下,您可以调用item.Create(...)。

Makes any sense for your case? 对您的情况有意义吗?

It sounds like you might be able to make your Button class generic. 听起来您也许可以使Button类成为通用类。 Depending on how much logic lives in each of these derived classes, this may not work for you. 根据这些派生类中每种逻辑的生存量,这可能对您不起作用。

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, ...);
    }
}

Then, to use this: 然后,使用此:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM