Класс.forName () эквивалентен в .NET? - PullRequest
12 голосов
/ 12 мая 2011

Как в C # можно динамически получать тип объекта и затем создавать его новые экземпляры?

например. Как мне добиться результата следующего кода Java, но в C #:

MyClass x = (MyClass) Class.forName("classes.MyChildClass").newInstance();

Ответы [ 4 ]

8 голосов
/ 12 мая 2011

Посмотрите на csharp-examples.net / mirror-examples .В основном вы должны использовать typeof() и Activator.createInstance().

5 голосов
/ 12 мая 2011

Этот вопрос состоит из двух частей

  1. Как получить Type, соответствующее имени?
    Иногда вы можете использовать Type.GetType(string). Но если тип не в mscorlib или в исполняющей сборке, вам нужно указать имя сборки в своем имени.

  2. Как создать данный тип?
    Activatior.CreateInstance ответ на эту часть.

Но в своем коде вы уже знаете класс, потому что вы можете привести к MyClass. Так что вопрос не имеет особого смысла.

4 голосов
/ 12 мая 2011

Простой пример:

namespace Your.Namespace
{
    public class Foo
    {
        public DateTime SixtyDaysFromNow()
        {
            return DateTime.Now + new TimeSpan(60,0,0,0);
        }
    }

    public class CreateInstance1
    {
        public static void Main(string[] args)
        {
            try
            {
                var x = Activator.CreateInstance(null, "Your.Namespace.Foo");
                Foo f = (Foo) x.Unwrap();
                Console.WriteLine("Result: {0}", f.SixtyDaysFromNow().ToString("G"));
            }
            catch (System.Exception exc1)
            {
                Console.WriteLine("Exception: {0}", exc1.ToString());
            }
        }
    }
}

Вызовите Activator.CreateInstance(), указав имя сборки и имя класса. Имя класса должно быть полностью квалифицированным (включая все пространства имен). Если имя сборки равно NULL, то используется текущая сборка. Если класс, который вы хотите активировать, находится за пределами текущей запущенной сборки, вам необходимо указать сборку с полным именем.

Чтобы загрузить из другой сборки, вам нужно использовать перегрузку для CreateInstance, которая принимает тип, а не имя типа; Один из способов получить тип для заданного имени типа - это использовать Type.GetType(), указав имя с указанием сборки.

Чаще всего Activator.CreateInstance() выполняется с использованием типов интерфейса, так что созданный экземпляр может быть приведен к интерфейсу, и вы можете вызывать его по типу интерфейса. как это:

    interface ISixty
    {
        DateTime SixtyDaysFromNow();
    }

    public class Foo : ISixty
    {
        public DateTime SixtyDaysFromNow()
        {
            return DateTime.Now + new TimeSpan(60,0,0,0);
        }
    }

и

  var x = Activator.CreateInstance(null, "Your.Namespace.Foo");
  ISixty f = (ISixty) x.Unwrap();
  Console.WriteLine("Sixty days from now: {0}", f.SixtyDaysFromNow().ToString("G"));

Делая это таким образом, ваше приложение (активирующее приложение) не должно знать или явно ссылаться на другую сборку во время компиляции.

3 голосов
/ 23 сентября 2013

Будьте предупреждены о постановке этого вопроса. Вопрос "Class.forName () эквивалентен в .NET?" и на этот вопрос фактически нет ответа на этой странице - у метода Class.forName () в Java есть один важный побочный эффект, которого нет у эквивалента .NET - то есть он фактически загружает класс. Так что, если вы имели в Java

Class c = Class.forName("mypackage.PardonMe");

Вам нужно ДВА оператора в C # /. NET, чтобы получить полный эффект:

Type t = Type.GetType("mypackage.PardonMe");
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(t.TypeHandle);

Это загружает класс без вызова статических методов или создания каких-либо экземпляров.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...