2013-07-31 3 views
3
Type thistype = stringVar.GetType(); 
thistype myScript = gameObject.AddComponent(stringVar); 

myScript.runCustomFunction(); 

Это не работает, и я считаю, что это потому, что я не могу бросить к переменной типа, если я не знаю, тип переменной во время компиляции (а не бежать), поэтому я не могу напрямую получить доступ к только что добавленному компоненту.Вызов функции на AddComponent (строковая переменная)

У меня есть класс gameItem, который извлекает значения по умолчанию из другого скрипта, а затем помещает их в словарь. Основываясь на словарной статье «functionScript», «myScript», мне нужно прикрепить myScript к объекту, а затем передать ему некоторые словарные записи.

В качестве альтернативы, я мог бы быть действительно неэффективным и спросить класс элемента для его переменных в классе myScript, который я бы предпочел избежать.

+1

Итак, у меня возникли проблемы с пониманием * именно того, чего вы пытаетесь достичь. Значение 'stringVar' - это что-то вроде' 'myScript'', и вам нужно уметь использовать соответствующий конкретный тип на основе имени? – Josh

+0

Строка stringVar равна «myScript» (или любое другое имя сценария, в зависимости от строки, переданной по умолчанию для значения элемента по умолчанию). Мне нужно использовать эту строку, чтобы добавить компонентный скрипт под названием myScript (или любое другое имя, все, что передано), а затем запустить функцию/передать некоторые переменные новому компоненту. – DigitalSalmon

+1

Но соответствует ли это конкретному типу? Вы, очевидно, знаете что-то об этом, иначе вы бы не стали называть 'runCustomFunction'. Все ли ваши типы наследуются от одного базового базового класса? Или реализовать интерфейс? – Josh

ответ

1

System.Type - это фактический тип, почти такой же, как System.Int32, или System.Guid. Вы не можете использовать переменную как статический идентификатор в своем коде, поскольку компилятор не знает, что это за тип.

I думаю то, что вы пытаетесь сделать, это построить конкретный тип, основанный на его названии.

Для этого вы можете использовать Activator.CreateInstance, если знаете имя и название сборки.

var typeName = "MyType"; 
var myType = Activator.CreateInstance("MyAssembly", typeName); 

Вы также можете использовать dynamic ключевое слово, чтобы позволить DLR обрабатывать тяжелую работу за вас.

dynamic myType = Activator.CreateInstance("MyAssembly", typeName); 
myType.runCustomFunction(); 

Если ваш тип наследует от общего базового типа, или реализует интерфейс, вы можете привести его к этому типу и вызову методы.

//Safe cast as base type 
var myType = Activator.CreateInstance("MyAssembly", typeName) as BaseType; 

//Or safe cast as interface 
var myType = Activator.CreateInstance("MyAssembly", typeName) as IMyType; 

Однако, если типы не наследуют от известного типа, но вы знаете, все они имеют метод, называемый runCustomFunction, и вы не хотите использовать dynamic, то вы можете использовать небольшое отражение в invoke that method.

//Create the System.Type using assembly qualified name 
var typeName = "MyType"; 
var assemblyQualifiedName = String.Format("MyAssembly.{0}", typeName); 
var myType = Type.GetType(assemblyQualifiedName); 

//Call activator overload, but `instance` is a System.Object 
var instance = Activator.CreateInstance(myType); 

//Use reflection to invoke the method 
myType.InvokeMember(
    "runCustomFunction", //member name 
    BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static, 
    null, //default binder 
    instance, //actual instance to invoke method on 
    null //no arguments so we use null 
); 

Как вы можете видеть, это намного проще просто сделать все ваши типы наследуют от некоторого базового класса или реализовать интерфейс, но можно, конечно, использовать отражение, если вы хотите сделать это трудный путь :)

+0

Массивные реквизиты для поиска времени, чтобы покрыть все возможности. Я прилагаю все усилия, чтобы найти ответы самостоятельно, однако - В этой ситуации, что представляет собой «MyAssembly»? – DigitalSalmon

+0

@DS Я также добавил параметр «dynamic» в список. Почти забыл об этом. В этом случае «MyAssembly» представляет имя сборки, тип которой определен. Обычно это то же самое, что и имя вашего проекта, но вы можете проверить свойства, чтобы быть уверенным. Например, если мой проект был назван 'JoshStuff', тогда мое имя сборки, скорее всего, будет таким же. – Josh

+0

Для справок в будущем - Казалось бы, ссылка Assembly для Unity3d - «Assembly-CSharp». 'вар TYPENAME = SCRIPTNAME;' ' вар MyType = Activator.CreateInstance ("монтажно-CSharp", TYPENAME);' \t \t 'MyType itemScript = gameObject.AddComponent (SCRIPTNAME);' , что код возвращает " Не удалось найти имя типа или пространства имен 'myType '. Вам не хватает директивы using или ссылки на сборку?" – DigitalSalmon

Смежные вопросы