от
Никто не может всегда знать
Type
объекта во время компиляции, но может потребоваться создать экземпляр
Type
. Как вы получаете новый экземпляр объекта из
Type
?

Ваш ответ

Отображаемое имя (по желанию):
Конфиденциальность: Ваш электронный адрес будет использоваться только для отправки уведомлений.

13 Ответы

0 голосов
от
Никто не может всегда знать
Type
объекта во время компиляции, но может потребоваться создать экземпляр
Type
. Как вы получаете новый экземпляр объекта из
Type
?
0 голосов
от
Класс
Activator
в корневом пространстве имен
System
довольно мощный. Есть много перегрузок для передачи параметров конструктору и такие. Проверить документацию на: на HTTP://msdn.microsoft.com/en-us/library/system.activator.createinstance.aspx или (Новый Путь) протокол HTTPS://docs.microsoft.com/en-us/dotnet/api/system.activator.createinstance Вот несколько простых примеров:
ObjectType instance = (ObjectType)Activator.CreateInstance(objectType);

ObjectType instance = (ObjectType)Activator.CreateInstance("MyAssembly","MyNamespace.ObjectType");
0 голосов
от
ObjectType instance = (ObjectType)Activator.CreateInstance(objectType);
Класс
Activator
есть универсальный вариант, который делает это немного проще:
ObjectType instance = Activator.CreateInstance
0 голосов
от
Скомпилированное выражение является наилучшим образом! (для выполнения многократного создания экземпляра во время выполнения).
static readonly Func
0 голосов
от
Одна из реализаций этой проблемы является попытка вызвать конструктор без параметров типа:
public static object GetNewObject(Type t)
{
    try
    {
        return t.GetConstructor(new Type[] { }).Invoke(new object[] { });
    }
    catch
    {
        return null;
    }
}
Здесь тот же подход, содержащийся в универсальный метод:
public static T GetNewObject
0 голосов
от
Его довольно просто. Предположим, что ваш className не
Car
и пространство имен
Vehicles
, затем передать параметр как
Vehicles.Car
который возвращает объект типа
Car
. Как это можно создать динамически любой экземпляр любого класса.
public object GetInstance(string strNamesapace)
{         
     Type t = Type.GetType(strNamesapace); 
     return  Activator.CreateInstance(t);         
}
Если ваше полное имя(т. е.
Vehicles.Car
в данном случае) находится в другой сборке,
Type.GetType
будет иметь значение null. В таких случаях вы должны перебрать все узлы и найти
Type
. Для этого вы можете использовать ниже код
public object GetInstance(string strFullyQualifiedName)
{
     Type type = Type.GetType(strFullyQualifiedName);
     if (type != null)
         return Activator.CreateInstance(type);
     foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
     {
         type = asm.GetType(strFullyQualifiedName);
         if (type != null)
             return Activator.CreateInstance(type);
     }
     return null;
 }
И вы можете получить экземпляр по телефонам указанным выше методом.
object objClassInstance = GetInstance("Vehicles.Car");
0 голосов
от
Если это то, что можно назвать много в экземпляре приложения, это намного быстрее, чтобы скомпилировать и кэш динамический код, а не использовать активатор или
ConstructorInfo.Invoke()
. Два простых вариантов для динамической компиляции запросов LINQ выражения или некоторые простые
IL
опкодов и
DynamicMethod
. В любом случае, разница огромная, когда вы начнете получать в петле или несколько вызовов.
0 голосов
от
Без использования отражения:
private T Create
0 голосов
от
Не универсальный
T t = new T();
работы?
0 голосов
от
Если вы хотите использовать конструктор по умолчанию, то решение с использованием
System.Activator
, представленные ранее-это, наверное, самый удобный. Однако, если тип не имеет конструктора по умолчанию, или вы должны использовать по умолчанию один, то как вариант-использовать отражение или
System.ComponentModel.TypeDescriptor
. В случае рефлексии, достаточно знать только имя типа (с пространством имен). Пример с помощью отражения:
ObjectType instance = 
    (ObjectType)System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(
        typeName: objectType.FulName, // string including namespace of the type
        ignoreCase: false,
        bindingAttr: BindingFlags.Default,
        binder: null,  // use default binder
        args: new object[] { args, to, constructor },
        culture: null, // use CultureInfo from current thread
        activationAttributes: null
    );
Пример использования
TypeDescriptor
:
ObjectType instance = 
    (ObjectType)System.ComponentModel.TypeDescriptor.CreateInstance(
        provider: null, // use standard type description provider, which uses reflection
        objectType: objectType,
        argTypes: new Type[] { types, of, args },
        args: new object[] { args, to, constructor }
    );
...