Создание объекта в Vala generic - PullRequest
0 голосов
/ 30 января 2019

Я хочу создать новый объект данного типа внутри универсального языка Vala.

class MyClass <T> : GLib.Object
{
    protected T data;

    public MyClass ()
    {
        data = new T ();
    }
}

Я понимаю, что это не может работать, но как это сделать?

1 Ответ

0 голосов
/ 30 января 2019

Вы, вероятно, лучше всего создаете его экземпляр при вызове конструктора для MyClass:

void main () {
    new MyClass<Test> (new Test ());
    new MyClass<Example> (new Example ());
}

class MyClass <T>
{
    protected T data;

    public MyClass (T data)
        {
            this.data = data;
        }
}

class Test {}

class Example {}

Обобщения Vala в настоящее время не предоставляют ограничений.Если вы собираетесь передать зависимость таким способом, вы можете рассмотреть возможность использования типа интерфейса вместо универсального типа.

Обновление

Если вы хотите реализовать фабрику, тогдаинтерфейс со статическим методом или функцией, вероятно, лучше:

void main () {
    var a = CommandFactory.get_command ("A");
    var b = CommandFactory.get_command ("B");

    a.run ();
    b.run ();
}

namespace CommandFactory {
    Command get_command (string criteria) {
        Command result = null;
        switch (criteria) {
            case "A":
                result = new CommandA ();
                break;
            case "B":
                result = new CommandB ();
                break;
            default:
                assert_not_reached ();
        }
        return result;
    }
}

interface Command:Object {
    public abstract void run ();
}

class CommandA:Object, Command {
    void run () { print ("A\n"); }
}

class CommandB:Object, Command {
    void run () { print ("B\n"); }
}

Я предполагаю, что под «абстрактным шаблоном ткани» вы подразумеваете «абстрактный фабричный шаблон»?Вы можете попробовать использовать самоанализ GType для создания экземпляра объекта, но это должен быть объект GObject, и вы пройдете проверку статического анализа Vala:

void main () {
    new MyClass<Example> (new Example ());

    /* These will fail at runtime
    new MyClass<string> ("this will fail at runtime");
    new MyClass<ThisWillFailAtRuntime> (new ThisWillFailAtRuntime ());
    */
}

class MyClass <T>
{
    protected T data;

    public MyClass (T data)
        {
            assert (typeof(T).is_object());
            this.data = Object.new (typeof(T));
        }
}

class Example:Object {}

class ThisWillFailAtRuntime {}

Обратите внимание, что Object.new() также является статическим методом.

Я не уверен, чего вы пытаетесь достичь, но вам, вероятно, лучше присмотреться к интерфейсам и отдать предпочтение композиции, а не наследованию в вашей объектной модели данных.

...