Как преобразовать объект, возвращаемый Activator.CreateInstance, в преобразованный тип? - PullRequest
1 голос
/ 22 апреля 2011

В приведенном ниже коде можно ли преобразовать x в тип, который вы передаете в Activator.CreateInstance, не зная, что это за время?Я попытался передать typeof..., но это не сработало.

var testClasses = AppDomain.CurrentDomain.GetAssemblies()
                  .Single(a=>a.FullName.StartsWith("VerifyStuff")).GetTypes()
                  .Where(t=>t.UnderlyingSystemType.Name.StartsWith("VerifyXXX"));

var x = Activator.CreateInstance(testClasses.ElementAt(0));

Спасибо!

1 Ответ

7 голосов
/ 22 апреля 2011

Вам просто нужно разыграть его:

MyObject x = (MyObject) Activator.CreateInstance(testClasses.ElementAt(0));

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

Редактировать:

можно ли преобразовать x втип, который вы передаете в Activator.CreateInstance, не зная, что он опередил?

, просто чтобы быть немного более понятным: x - это типа, который вы передали в CreateInstance, но он приведен как объект, потому что CreateInstance не имеет представления о том, что вы можете к нему добавить.Ваша проблема возникает после того, как вы создали свой конкретный экземпляр - вы не можете передать его в другую (строго типизированную) функцию, потому что она у вас есть как object.Есть несколько способов обойти это:

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

  • если у вас есть функция, которая должна выполнять операцию с этими конкретными экземплярами, создайте для этого универсальную функцию:

    
    public T MyFunc(T myConcreteInstance) 
    {
        ... do whatever it is i need to do...
    }
    
  • это уродливо, но может быть трудно избежать ... используйте большой оператор if..else if , чтобы определить их типы, прежде чем работать с ними (подсказка: чтобы избежать этого варианта использования # 1выше ...):

    
    Type t = myConcreteInstance.GetType();
    if (t == typeof(someType1))
    {
    
    }
    else if (t == typeof(someType2))
    {
    
    }
    ... etc ...
    

Если в этот момент вы думаете «почему бы мне просто не сделать общую версию CreateInstance ()?» тогда не беспокойтесь - он уже есть, он по-прежнему не решает проблему строгой типизации вещей перед их передачей.Процитируем MSDN:

Как правило, CreateInstance не используется в коде приложения, потому что тип должен быть известен во время компиляции.Если тип известен во время компиляции, можно использовать обычный синтаксис создания экземпляра (оператор new в C #, оператор New в Visual Basic, gcnew в C ++).

Если вы собираетесь использовать CreateInstance, это потому, что вы не знаете тип заранее , поэтому вы должны обойти его.

...